8 Commits

Author SHA1 Message Date
Christian Knaapen
62d1c4a935 More compile error fixes. 2023-09-23 13:23:58 +02:00
Christian Knaapen
a578860e86 Changed most GUI stuff to use GuiGraphics instead of PoseStacks. 2023-09-16 15:18:18 +02:00
Christian Knaapen
37d16cd7b1 Updated outliner. 2023-09-16 13:32:14 +02:00
Christian Knaapen
9f05c218c7 Updated custom create classes. 2023-09-16 13:09:07 +02:00
Christian Knaapen
8c2b9cb240 Updated Create files to 1.20 2023-09-16 12:42:42 +02:00
Christian Knaapen
d8f47db7fa Replaced Widget with Renderable. BlockPos doubles constructor is now BlockPos.containing().
GetBlitOffset is replaced with ms.z, doing 0 for now.
Block Materials have been removed.
2023-07-29 19:35:58 +02:00
Christian Knaapen
ee9b61f7fe Added creative mode tab. Replaced player.level with level(). Replaced mojang.math with org.joml.
Using new SoundEvent.createVariableRangeEvent.
2023-07-29 18:02:30 +02:00
Christian Knaapen
4158ed254d Updated properties to 1.20. Gradle to 8.1. 2023-07-29 16:17:13 +02:00
207 changed files with 5131 additions and 2087 deletions

6
.gitignore vendored
View File

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

View File

@@ -1,94 +1,101 @@
plugins { buildscript {
id "idea" repositories {
id "eclipse" maven { url = 'https://maven.minecraftforge.net' }
id "maven-publish" mavenCentral()
id 'net.neoforged.moddev.legacyforge' version '2.0.78' jcenter()
id "org.jetbrains.gradle.plugin.idea-ext" version "1.1.8" // https://github.com/JetBrains/gradle-idea-ext-plugin maven { url = 'https://repo.spongepowered.org/repository/maven-public' }
id "net.darkhax.curseforgegradle" version "1.1.26" 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}"
}
} }
apply from: "./gradle/java.gradle" plugins {
apply from: "gradle/property_loader.gradle" 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 flywheelInWorkspace = findProject(':Flywheel') != null
ext.buildNumber = System.getenv('BUILD_NUMBER') ext.buildNumber = System.getenv('BUILD_NUMBER')
version = mod_version
group = 'nl.requios.effortlessbuilding' group = 'nl.requios.effortlessbuilding'
base { archivesBaseName = "effortlessbuilding-${artifact_minecraft_version}"
archivesName = "effortlessbuilding-${artifact_minecraft_version}"
version = mod_version
}
java.toolchain.languageVersion = JavaLanguageVersion.of(17) java.toolchain.languageVersion = JavaLanguageVersion.of(17)
println('Java: ' + System.getProperty('java.version') + ' JVM: ' + System.getProperty('java.vm.version') + ' (' + System.getProperty('java.vendor') + ') Arch: ' + System.getProperty('os.arch')) println('Java: ' + System.getProperty('java.version') + ' JVM: ' + System.getProperty('java.vm.version') + ' (' + System.getProperty('java.vendor') + ') Arch: ' + System.getProperty('os.arch'))
legacyForge { minecraft {
version = "$minecraft_version-$forge_version" mappings channel: 'parchment', version: "${parchment_version}-${minecraft_version}"
accessTransformer = file('src/main/resources/META-INF/accesstransformer.cfg')
if (file('src/main/resources/META-INF/accesstransformer.cfg').exists()) {
accessTransformers.from "src/main/resources/META-INF/accesstransformer.cfg"
}
parchment {
minecraftVersion = minecraft_version
mappingsVersion = parchment_version
}
runs { runs {
// applies to all the run configs below
configureEach {
systemProperty 'forge.logging.markers', ''
systemProperty 'forge.logging.console.level', 'info'
jvmArguments = ["-XX:+IgnoreUnrecognizedVMOptions", "-XX:+AllowEnhancedClassRedefinition"]
//jvmArgs("-XX:-OmitStackTraceInFastThrow") // uncomment when you get exceptions with null messages etc
//jvmArgs '-XX:+UnlockCommercialFeatures' // uncomment for profiling
systemProperty 'mixin.debug.export', 'true'
systemProperty 'mixin.debug.verbose', 'true'
}
client { client {
client() workingDirectory project.file('run')
arg '-mixin.config=flywheel.mixins.json'
//jvmArgs '-XX:+UnlockCommercialFeatures' // uncomment for profiling
property 'forge.logging.console.level', 'info'
gameDirectory = project.file('run') mods {
effortlessbuilding {
source sourceSets.main
}
if (flywheelInWorkspace) {
flywheel {
source project(":Flywheel").sourceSets.main
}
}
}
} }
server { server {
server() workingDirectory project.file('run/server')
property 'forge.logging.console.level', 'info'
gameDirectory = project.file('run/server') mods {
effortlessbuilding {
source sourceSets.main
}
}
} }
data { data {
data() workingDirectory project.file('run')
property 'forge.logging.markers', 'REGISTRIES,REGISTRYDUMP'
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
}
gameDirectory = project.file('run') if (flywheelInWorkspace) {
systemProperty 'forge.logging.markers', 'REGISTRIES,REGISTRYDUMP' flywheel {
systemProperty 'forge.logging.console.level', 'debug' source project(":Flywheel").sourceSets.main
programArguments.addAll("--mod", mod_id as String, "--all", "--output", file("src/generated/resources/").getAbsolutePath(), "--existing", file("src/main/resources").getAbsolutePath()) }
} }
}
gameTestServer {
type = "gameTestServer"
gameDirectory = project.file('run/gametest')
// setForceExit false <- FIXME 1.20
}
}
mods {
effortlessbuilding {
sourceSet sourceSets.main
} }
} }
} }
// Include resources generated by data generators.
sourceSets.main.resources { srcDir 'src/generated/resources' }
repositories { repositories {
maven { url = "https://maven.createmod.net" } // Ponder, Flywheel maven {
maven { url = "https://maven.tterrag.com" } // Registrate // location of the maven for Registrate and Flywheel
name = 'tterrag maven'
url = 'https://maven.tterrag.com'
}
maven { maven {
url = 'https://www.cursemaven.com' url = 'https://www.cursemaven.com'
@@ -111,26 +118,23 @@ repositories {
} }
dependencies { dependencies {
jarJar("net.createmod.ponder:Ponder-Forge-${minecraft_version}:${ponder_version}") minecraft "net.minecraftforge:forge:${minecraft_version}-${forge_version}"
modCompileOnly("dev.engine-room.flywheel:flywheel-forge-api-${flywheel_minecraft_version}:${flywheel_version}") jarJar("com.jozufozu.flywheel:flywheel-forge-${flywheel_minecraft_version}:${flywheel_version}") {
modRuntimeOnly(jarJar("dev.engine-room.flywheel:flywheel-forge-${flywheel_minecraft_version}:${flywheel_version}") { jarJar.ranged(it, '[0.6.9,0.6.10)')
version { }
strictly "[1.0,2.0)"
prefer flywheel_version
}
})
modRuntimeOnly("dev.engine-room.vanillin:vanillin-forge-${flywheel_minecraft_version}:${vanillin_version}")
modImplementation("net.createmod.ponder:Ponder-Forge-${minecraft_version}:${ponder_version}") if (flywheelInWorkspace) {
implementation project(':Flywheel')
} else {
implementation fg.deobf("com.jozufozu.flywheel:flywheel-forge-${flywheel_minecraft_version}:${flywheel_version}")
}
// Prevent Mixin annotation processor from getting into IntelliJ's annotation processor settings // 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 // 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')) { if (!Boolean.getBoolean('idea.sync.active')) {
annotationProcessor "org.spongepowered:mixin:${mixin_version}:processor" annotationProcessor "org.spongepowered:mixin:${mixin_version}:processor"
} }
compileOnly('org.jetbrains:annotations:24.0.1')
} }
sourceSets.main.resources { sourceSets.main.resources {
@@ -141,13 +145,6 @@ 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 {
module {
downloadJavadoc = true
downloadSources = true
}
}
compileJava { compileJava {
options.compilerArgs = ['-Xdiags:verbose'] options.compilerArgs = ['-Xdiags:verbose']
} }
@@ -155,13 +152,13 @@ compileJava {
jar { jar {
manifest { manifest {
attributes([ attributes([
"Specification-Title" : mod_id, "Specification-Title": "effortlessbuilding",
"Specification-Vendor" : mod_author, "Specification-Vendor": "requios",
"Specification-Version" : "1", "Specification-Version": "1",
"Implementation-Title" : project.name, "Implementation-Title": project.jar.archiveBaseName,
"Implementation-Version" : project.jar.archiveVersion, "Implementation-Version": project.jar.archiveVersion,
"Implementation-Vendor" : mod_author, "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")
]) ])
} }
} }
@@ -170,7 +167,7 @@ task jarJarRelease {
group = 'jarjar' group = 'jarjar'
doLast { doLast {
tasks.jarJar { tasks.jarJar {
classifier = '' archiveClassifier = ''
} }
} }
finalizedBy tasks.jarJar finalizedBy tasks.jarJar
@@ -181,17 +178,24 @@ java {
withJavadocJar() withJavadocJar()
} }
tasks.build.dependsOn tasks.jarJar jar.finalizedBy('reobfJar')
tasks.jarJar.finalizedBy('reobfJarJar')
project.publishing { publishing {
publications { publications {
mavenJava(MavenPublication) { mavenJava(MavenPublication) {
artifactId base.archivesName.get() artifactId = archivesBaseName
from components.java
artifact(tasks.jar) { from components.java
classifier = "all" fg.component(it)
} jarJar.component(it)
}
}
repositories {
if (project.hasProperty('mavendir')) {
maven { url mavendir }
} }
} }
} }

View File

@@ -3,27 +3,18 @@
org.gradle.jvmargs=-Xmx3G org.gradle.jvmargs=-Xmx3G
org.gradle.daemon=false org.gradle.daemon=false
mod_version = 3.10 mod_version = 3.4
artifact_minecraft_version = 1.20.1 artifact_minecraft_version = 1.20.1
minecraft_version = 1.20.1 minecraft_version = 1.20.1
forge_version = 47.1.3 forge_version = 47.0.43
forgegradle_version = 6.0.7 forgegradle_version = 6.0.6
mixingradle_version = 0.7-SNAPSHOT mixingradle_version = 0.7-SNAPSHOT
mixin_version = 0.8.5 mixin_version = 0.8.5
librarian_version = 1.+ librarian_version = 1.+
cursegradle_version = 1.4.0 cursegradle_version = 1.4.0
parchment_version = 2023.09.03 parchment_version = 2023.06.26
flywheel_minecraft_version = 1.20.1 flywheel_minecraft_version = 1.20.1
flywheel_version = 1.0.1 flywheel_version = 0.6.9-5
vanillin_version = 1.0.0-beta-217
ponder_version = 1.0.51
# mod options
mod_id = effortlessbuilding
mod_name = Effortless Building
mod_author = Requios
mod_description = Makes building easier by providing tools like mirrors, arrays, build modes and a block randomizer. For survival and creative mode.
mod_license = GNU LGPLv3

View File

@@ -1,39 +0,0 @@
apply plugin: 'java'
java.toolchain.languageVersion = JavaLanguageVersion.of(17)
java.withSourcesJar()
java.withJavadocJar()
jar {
manifest {
attributes([
'Specification-Title' : mod_name,
'Specification-Vendor' : mod_author,
'Specification-Version' : project.jar.archiveVersion,
'Implementation-Title' : project.name,
'Implementation-Version' : project.jar.archiveVersion,
'Implementation-Vendor' : mod_author,
'Implementation-Timestamp': new Date().format("yyyy-MM-dd'T'HH:mm:ssZ"),
'Timestampe' : System.currentTimeMillis(),
'Built-On-Java' : "${System.getProperty('java.vm.version')} (${System.getProperty('java.vm.vendor')})",
'Built-On-Minecraft' : minecraft_version
])
}
}
tasks.withType(JavaCompile).configureEach {
it.options.encoding = 'UTF-8'
it.options.release = 17
}
// Disables Gradle's custom module metadata from being published to maven. The
// metadata includes mapped dependencies which are not reasonably consumable by
// other mod developers.
tasks.withType(GenerateModuleMetadata) {
enabled = false
}
javadoc {
// Suppress annoying warnings when generating JavaDoc files.
options.addStringOption('Xdoclint:none', '-quiet')
}

View File

@@ -1,48 +0,0 @@
/*
This module can inject build properties from a JSON file. Each property in the
JSON file will be mapped to a build property using the key of that property.
Property keys ending with _comment will be skipped.
If a secretFile property exists and points to a valid JSON file that file will
be automatically loaded. You can manually load a file using the loadProperties
method.
*/
import groovy.json.JsonSlurper
// Auto detects a secret file and injects it.
if (project.rootProject.hasProperty("secretFile")) {
project.logger.lifecycle("Automatically loading properties from the secretFile")
final def secretsFile = project.rootProject.file(project.rootProject.getProperty("secretFile"))
if (secretsFile.exists() && secretsFile.name.endsWith(".json")) {
loadProperties(secretsFile)
}
}
// Loads properties using a specified json file.
def loadProperties(propertyFile) {
if (propertyFile.exists()) {
propertyFile.withReader {
Map propMap = new JsonSlurper().parse it
for (entry in propMap) {
// Filter entries that use _comment in the key.
if (!entry.key.endsWith("_comment")) {
project.ext.set(entry.key, entry.value)
}
}
project.logger.lifecycle("Successfully loaded " + propMap.size() + " properties")
propMap.clear()
}
} else {
project.logger.warn("The property file " + propertyFile.getName() + " could not be loaded. It does not exist.")
}
}
// Allows other scripts to use these methods.
ext {
loadProperties = this.&loadProperties
}

Binary file not shown.

View File

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

28
gradlew vendored
View File

@@ -1,7 +1,7 @@
#!/bin/sh #!/bin/sh
# #
# Copyright © 2015-2021 the original authors. # Copyright <EFBFBD> 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.
@@ -32,10 +32,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 «$var», «${var}», «${var:-default}», «${var+SET}», # * expansions <EFBFBD>$var<EFBFBD>, <EFBFBD>${var}<EFBFBD>, <EFBFBD>${var:-default}<EFBFBD>, <EFBFBD>${var+SET}<EFBFBD>,
# «${var#prefix}», «${var%suffix}», and «$( cmd )»; # <EFBFBD>${var#prefix}<EFBFBD>, <EFBFBD>${var%suffix}<EFBFBD>, and <EFBFBD>$( cmd )<EFBFBD>;
# * compound commands having a testable exit status, especially «case»; # * compound commands having a testable exit status, especially <EFBFBD>case<EFBFBD>;
# * various built-in commands including «command», «set», and «ulimit». # * various built-in commands including <EFBFBD>command<EFBFBD>, <EFBFBD>set<EFBFBD>, and <EFBFBD>ulimit<EFBFBD>.
# #
# Important for patching: # Important for patching:
# #
@@ -55,7 +55,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/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # https://github.com/gradle/gradle/blob/master/subprojects/plugins/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,11 +80,11 @@ do
esac esac
done done
# This is normally unused
# shellcheck disable=SC2034
APP_BASE_NAME=${0##*/}
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
APP_NAME="Gradle"
APP_BASE_NAME=${0##*/}
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
@@ -143,16 +143,12 @@ fi
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=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=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
@@ -209,12 +205,6 @@ 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.

15
gradlew.bat vendored
View File

@@ -14,7 +14,7 @@
@rem limitations under the License. @rem limitations under the License.
@rem @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,8 +25,7 @@
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%
@@ -41,7 +40,7 @@ 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% equ 0 goto execute if "%ERRORLEVEL%" == "0" goto execute
echo. echo.
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.
@@ -76,15 +75,13 @@ 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% equ 0 goto mainEnd if "%ERRORLEVEL%"=="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!
set EXIT_CODE=%ERRORLEVEL% if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
if %EXIT_CODE% equ 0 set EXIT_CODE=1 exit /b 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,15 +1 @@
pluginManagement { rootProject.name = 'EffortlessBuilding'
repositories {
gradlePluginPortal()
mavenCentral()
maven { url = 'https://maven.minecraftforge.net/' }
maven { url = 'https://repo.spongepowered.org/repository/maven-public' }
maven { url = 'https://maven.parchmentmc.org' }
}
}
plugins {
id 'org.gradle.toolchains.foojay-resolver-convention' version '0.8.0'
}
rootProject.name = 'Effortless Building'

View File

@@ -48,14 +48,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(GuiGraphics ms, int x, int y) { bind();
ms.blit(location, x, y, 0, startX, startY, width, height, 256, 256); graphics.blit(location, x, y, startX, startY, width, height, width, height);
} }
@OnlyIn(Dist.CLIENT) @OnlyIn(Dist.CLIENT)
public void render(GuiGraphics ms, int x, int y, Color c) { public void render(GuiGraphics graphics, int x, int y, Color c) {
bind(); bind();
UIRenderHelper.drawColoredTexture(ms, c, x, y, startX, startY, width, height); UIRenderHelper.drawColoredTexture(graphics, c, x, y, startX, startY, width, height);
} }
} }

View File

@@ -1,8 +1,10 @@
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 net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.GuiGraphics;
import org.joml.Matrix4f;
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;
@@ -14,7 +16,6 @@ import nl.requios.effortlessbuilding.create.Create;
import nl.requios.effortlessbuilding.create.foundation.gui.element.DelegatedStencilElement; import nl.requios.effortlessbuilding.create.foundation.gui.element.DelegatedStencilElement;
import nl.requios.effortlessbuilding.create.foundation.gui.element.ScreenElement; import nl.requios.effortlessbuilding.create.foundation.gui.element.ScreenElement;
import nl.requios.effortlessbuilding.create.foundation.utility.Color; import nl.requios.effortlessbuilding.create.foundation.utility.Color;
import org.joml.Matrix4f;
public class AllIcons implements ScreenElement { public class AllIcons implements ScreenElement {
@@ -99,13 +100,19 @@ 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)
public void bind() {
RenderSystem.setShaderTexture(0, ICON_ATLAS);
}
@OnlyIn(Dist.CLIENT) @OnlyIn(Dist.CLIENT)
@Override @Override
public void render(GuiGraphics guiGraphics, int x, int y) { public void render(GuiGraphics graphics, int x, int y) {
guiGraphics.blit(ICON_ATLAS, x, y, 0, iconX, iconY, 16, 16, 256, 256); bind();
graphics.blit(ICON_ATLAS, x, y, 0, iconX, iconY, 16, 16, 256, 256);
} }
@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));

View File

@@ -17,10 +17,10 @@ import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod.EventBusSubscriber; import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
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.capability.CapabilityHandler;
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)
@@ -134,7 +134,7 @@ public class ClientEvents {
//Radial menu //Radial menu
if (keyBindings[0].isDown()) { if (keyBindings[0].isDown()) {
if (!CapabilityHandler.isDisabled(player)) { if (!EffortlessBuildingClient.POWER_LEVEL.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 (CapabilityHandler.isDisabled(player)) { if (EffortlessBuildingClient.POWER_LEVEL.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());

View File

@@ -2,12 +2,11 @@ package nl.requios.effortlessbuilding;
import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.InteractionHand; import net.minecraft.world.InteractionHand;
import net.minecraft.world.entity.Entity;
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.CreativeModeTabRegistry;
import net.minecraftforge.common.util.FakePlayer; import net.minecraftforge.common.util.FakePlayer;
import net.minecraftforge.event.AttachCapabilitiesEvent;
import net.minecraftforge.event.RegisterCommandsEvent; import net.minecraftforge.event.RegisterCommandsEvent;
import net.minecraftforge.event.TickEvent; import net.minecraftforge.event.TickEvent;
import net.minecraftforge.event.entity.player.PlayerEvent; import net.minecraftforge.event.entity.player.PlayerEvent;
@@ -16,13 +15,9 @@ import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.LogicalSide; import net.minecraftforge.fml.LogicalSide;
import net.minecraftforge.fml.common.Mod.EventBusSubscriber; import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
import net.minecraftforge.network.PacketDistributor; import net.minecraftforge.network.PacketDistributor;
import nl.requios.effortlessbuilding.capability.CapabilityHandler;
import nl.requios.effortlessbuilding.capability.IPowerLevel;
import nl.requios.effortlessbuilding.capability.PowerLevelCapability;
import nl.requios.effortlessbuilding.compatibility.CompatHelper; import nl.requios.effortlessbuilding.compatibility.CompatHelper;
import nl.requios.effortlessbuilding.network.ModifierSettingsPacket; import nl.requios.effortlessbuilding.network.ModifierSettingsPacket;
import nl.requios.effortlessbuilding.network.PacketHandler; import nl.requios.effortlessbuilding.network.PacketHandler;
import nl.requios.effortlessbuilding.network.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;
@@ -80,10 +75,7 @@ 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;
IPowerLevel powerLevel = player.getCapability(CapabilityHandler.POWER_LEVEL_CAPABILITY).orElse(null); if (!ServerBuildState.isLikeVanilla(player) && EffortlessBuilding.SERVER_POWER_LEVEL.canBreakFar(player)) {
if (powerLevel == null) return; //Should never be null but just to be sure
if (!ServerBuildState.isLikeVanilla(player) && powerLevel.canBreakFar(player)) {
event.setCanceled(true); event.setCanceled(true);
} }
} }
@@ -103,34 +95,7 @@ public class CommonEvents {
ServerBuildState.handleNewPlayer(player); ServerBuildState.handleNewPlayer(player);
PacketHandler.INSTANCE.send(PacketDistributor.PLAYER.with(() -> (ServerPlayer) player), new ModifierSettingsPacket(player)); PacketHandler.INSTANCE.send(PacketDistributor.PLAYER.with(() -> (ServerPlayer) player), new ModifierSettingsPacket(player));
EffortlessBuilding.SERVER_POWER_LEVEL.sendToClient(player);
IPowerLevel powerLevel = player.getCapability(CapabilityHandler.POWER_LEVEL_CAPABILITY).orElse(null);
if (powerLevel == null) return; //Should never be null but just to be sure
PacketHandler.INSTANCE.send(PacketDistributor.PLAYER.with(() -> (ServerPlayer) player), new PowerLevelPacket(powerLevel.getPowerLevel()));
}
@SubscribeEvent
public static void registerCaps(AttachCapabilitiesEvent<Entity> event) {
if (event.getObject() instanceof Player) {
event.addCapability(CapabilityHandler.POWER_LEVEL_CAP, new PowerLevelCapability());
}
}
@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
original.getCapability(CapabilityHandler.POWER_LEVEL_CAPABILITY).ifPresent(dataOriginal ->
clone.getCapability(CapabilityHandler.POWER_LEVEL_CAPABILITY).ifPresent(dataClone -> {
dataClone.setPowerLevel(dataOriginal.getPowerLevel());
})
);
} }
@SubscribeEvent @SubscribeEvent

View File

@@ -0,0 +1,21 @@
package nl.requios.effortlessbuilding;
import net.minecraft.world.item.CreativeModeTab;
public class EBCreativeModeTab implements CreativeModeTab.DisplayItemsGenerator {
@Override
public void accept(CreativeModeTab.ItemDisplayParameters pParameters, CreativeModeTab.Output pOutput) {
pOutput.accept(EffortlessBuilding.RANDOMIZER_BAG_ITEM.get());
pOutput.accept(EffortlessBuilding.GOLDEN_RANDOMIZER_BAG_ITEM.get());
pOutput.accept(EffortlessBuilding.DIAMOND_RANDOMIZER_BAG_ITEM.get());
pOutput.accept(EffortlessBuilding.REACH_UPGRADE_1_ITEM.get());
pOutput.accept(EffortlessBuilding.REACH_UPGRADE_2_ITEM.get());
pOutput.accept(EffortlessBuilding.REACH_UPGRADE_3_ITEM.get());
pOutput.accept(EffortlessBuilding.MUSCLES_ITEM.get());
pOutput.accept(EffortlessBuilding.ELASTIC_HAND_ITEM.get());
pOutput.accept(EffortlessBuilding.BUILDING_TECHNIQUES_BOOK_ITEM.get());
}
}

View File

@@ -1,18 +1,18 @@
package nl.requios.effortlessbuilding; package nl.requios.effortlessbuilding;
import com.mojang.serialization.Codec; import com.mojang.serialization.Codec;
import net.minecraft.core.registries.Registries;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.Player;
import net.minecraft.world.flag.FeatureFlags; import net.minecraft.world.flag.FeatureFlagSet;
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.CreativeModeTabs; 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.minecraft.world.item.ItemStack;
import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.common.loot.IGlobalLootModifier; import net.minecraftforge.common.loot.IGlobalLootModifier;
import net.minecraftforge.event.BuildCreativeModeTabContentsEvent;
import net.minecraftforge.eventbus.api.IEventBus; import net.minecraftforge.eventbus.api.IEventBus;
import net.minecraftforge.fml.DistExecutor; import net.minecraftforge.fml.DistExecutor;
import net.minecraftforge.fml.ModLoadingContext; import net.minecraftforge.fml.ModLoadingContext;
@@ -35,12 +35,11 @@ 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;
@Mod(EffortlessBuilding.MODID) @Mod(EffortlessBuilding.MODID)
public class EffortlessBuilding { public class EffortlessBuilding {
@@ -53,11 +52,13 @@ public class EffortlessBuilding {
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<Item> ITEMS = DeferredRegister.create(ForgeRegistries.ITEMS, MODID);
private static final DeferredRegister<MenuType<?>> CONTAINERS = DeferredRegister.create(ForgeRegistries.MENU_TYPES, EffortlessBuilding.MODID); private static final DeferredRegister<MenuType<?>> CONTAINERS = DeferredRegister.create(ForgeRegistries.MENU_TYPES, EffortlessBuilding.MODID);
public static final DeferredRegister<Codec<? extends IGlobalLootModifier>> LOOT_MODIFIERS = DeferredRegister.create(ForgeRegistries.Keys.GLOBAL_LOOT_MODIFIER_SERIALIZERS, 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<CreativeModeTab> CREATIVE_TABS = DeferredRegister.create(Registries.CREATIVE_MODE_TAB, EffortlessBuilding.MODID);
public static final RegistryObject<Item> RANDOMIZER_BAG_ITEM = ITEMS.register("randomizer_bag", RandomizerBagItem::new); public static final RegistryObject<Item> 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 RegistryObject<Item> GOLDEN_RANDOMIZER_BAG_ITEM = ITEMS.register("golden_randomizer_bag", GoldenRandomizerBagItem::new);
@@ -73,6 +74,12 @@ public class EffortlessBuilding {
public static final RegistryObject<MenuType<GoldenRandomizerBagContainer>> GOLDEN_RANDOMIZER_BAG_CONTAINER = CONTAINERS.register("golden_randomizer_bag", () -> registerContainer(GoldenRandomizerBagContainer::new)); public static final RegistryObject<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 RegistryObject<MenuType<DiamondRandomizerBagContainer>> DIAMOND_RANDOMIZER_BAG_CONTAINER = CONTAINERS.register("diamond_randomizer_bag", () -> registerContainer(DiamondRandomizerBagContainer::new));
public static final RegistryObject<CreativeModeTab> CREATIVE_TAB = CREATIVE_TABS.register("effortlessbuilding",
() -> CreativeModeTab.builder()
.title(Component.translatable("key.effortlessbuilding.category"))
.icon(() -> new ItemStack(RANDOMIZER_BAG_ITEM.get()))
.displayItems(new EBCreativeModeTab())
.build());
public EffortlessBuilding() { public EffortlessBuilding() {
instance = this; instance = this;
@@ -82,7 +89,6 @@ public class EffortlessBuilding {
IEventBus forgeEventBus = MinecraftForge.EVENT_BUS; IEventBus forgeEventBus = MinecraftForge.EVENT_BUS;
modEventBus.addListener(EffortlessBuilding::setup); modEventBus.addListener(EffortlessBuilding::setup);
modEventBus.addListener(EffortlessBuilding::addTabContents);
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> EffortlessBuildingClient.onConstructorClient(modEventBus, forgeEventBus)); DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> EffortlessBuildingClient.onConstructorClient(modEventBus, forgeEventBus));
@@ -92,10 +98,12 @@ public class EffortlessBuilding {
var singleItemLootModifier = SingleItemLootModifier.CODEC; //load this class to register the loot modifier var singleItemLootModifier = SingleItemLootModifier.CODEC; //load this class to register the loot modifier
LOOT_MODIFIERS.register(FMLJavaModLoadingContext.get().getModEventBus()); LOOT_MODIFIERS.register(FMLJavaModLoadingContext.get().getModEventBus());
CREATIVE_TABS.register(FMLJavaModLoadingContext.get().getModEventBus());
//Register config //Register config
modLoadingContext.registerConfig(ModConfig.Type.COMMON, CommonConfig.spec); ModLoadingContext.get().registerConfig(ModConfig.Type.COMMON, CommonConfig.spec);
modLoadingContext.registerConfig(ModConfig.Type.CLIENT, ClientConfig.spec); ModLoadingContext.get().registerConfig(ModConfig.Type.CLIENT, ClientConfig.spec);
modLoadingContext.registerConfig(ModConfig.Type.SERVER, ServerConfig.spec); ModLoadingContext.get().registerConfig(ModConfig.Type.SERVER, ServerConfig.spec);
} }
public static void setup(final FMLCommonSetupEvent event) { public static void setup(final FMLCommonSetupEvent event) {
@@ -104,15 +112,8 @@ public class EffortlessBuilding {
CompatHelper.setup(); CompatHelper.setup();
} }
public static void addTabContents(final BuildCreativeModeTabContentsEvent event) {
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){ public static <T extends AbstractContainerMenu> MenuType<T> registerContainer(IContainerFactory<T> fact){
MenuType<T> type = new MenuType<T>(fact, FeatureFlags.REGISTRY.allFlags()); MenuType<T> type = new MenuType<T>(fact, FeatureFlagSet.of());
return type; return type;
} }

View File

@@ -20,6 +20,7 @@ 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::clientSetup);

View File

@@ -1,16 +1,16 @@
package nl.requios.effortlessbuilding.buildmode; package nl.requios.effortlessbuilding.buildmode;
import nl.requios.effortlessbuilding.create.foundation.utility.Color; import org.joml.Vector4f;
public enum BuildModeCategoryEnum { public enum BuildModeCategoryEnum {
BASIC(new Color(0f, .5f, 1f, .8f)), BASIC(new Vector4f(0f, .5f, 1f, .8f)),
DIAGONAL(new Color(0.56f, 0.28f, 0.87f, .8f)), DIAGONAL(new Vector4f(0.56f, 0.28f, 0.87f, .8f)),
CIRCULAR(new Color(0.29f, 0.76f, 0.3f, 1f)), CIRCULAR(new Vector4f(0.29f, 0.76f, 0.3f, 1f)),
ROOF(new Color(0.83f, 0.87f, 0.23f, .8f)); ROOF(new Vector4f(0.83f, 0.87f, 0.23f, .8f));
public final Color color; public final Vector4f color;
BuildModeCategoryEnum(Color color) { BuildModeCategoryEnum(Vector4f color) {
this.color = color; this.color = color;
} }
} }

View File

@@ -5,7 +5,6 @@ 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.capability.CapabilityHandler;
import nl.requios.effortlessbuilding.utilities.BlockEntry; import nl.requios.effortlessbuilding.utilities.BlockEntry;
import nl.requios.effortlessbuilding.utilities.BlockSet; import nl.requios.effortlessbuilding.utilities.BlockSet;
@@ -65,7 +64,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 = CapabilityHandler.getMaxBlocksPerAxis(player, false); int axisLimit = EffortlessBuildingClient.POWER_LEVEL.getMaxBlocksPerAxis(player);
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();
@@ -94,7 +93,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 = CapabilityHandler.getMaxBlocksPerAxis(player, false); int axisLimit = EffortlessBuildingClient.POWER_LEVEL.getMaxBlocksPerAxis(player);
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();
@@ -140,7 +139,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 = CapabilityHandler.getBuildModeReach(player); int reach = EffortlessBuildingClient.POWER_LEVEL.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

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.capability.CapabilityHandler;
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 = CapabilityHandler.getMaxBlocksPerAxis(player, false); int axisLimit = EffortlessBuildingClient.POWER_LEVEL.getMaxBlocksPerAxis(player);
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

@@ -3,10 +3,11 @@ package nl.requios.effortlessbuilding.buildmode.buildmodes;
import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.Player;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.world.phys.Vec3; import net.minecraft.world.phys.Vec3;
import nl.requios.effortlessbuilding.EffortlessBuildingClient;
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.capability.CapabilityHandler; import nl.requios.effortlessbuilding.systems.PowerLevel;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@@ -24,7 +25,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 = CapabilityHandler.getBuildModeReach(player); int reach = EffortlessBuildingClient.POWER_LEVEL.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

View File

@@ -1,11 +1,12 @@
package nl.requios.effortlessbuilding.buildmode.buildmodes; package nl.requios.effortlessbuilding.buildmode.buildmodes;
import net.minecraft.core.BlockPos;
import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.Player;
import net.minecraft.core.BlockPos;
import net.minecraft.world.phys.Vec3; import net.minecraft.world.phys.Vec3;
import nl.requios.effortlessbuilding.EffortlessBuildingClient;
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.capability.CapabilityHandler; import nl.requios.effortlessbuilding.systems.PowerLevel;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@@ -31,7 +32,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 = CapabilityHandler.getBuildModeReach(player); int reach = EffortlessBuildingClient.POWER_LEVEL.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
@@ -89,7 +90,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(BlockPos.containing(x, y, z)); list.add(new BlockPos(x, y, z));
} }
} }

View File

@@ -2,9 +2,10 @@ package nl.requios.effortlessbuilding.buildmode.buildmodes;
import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.Player;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import nl.requios.effortlessbuilding.EffortlessBuildingClient;
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.capability.CapabilityHandler; import nl.requios.effortlessbuilding.systems.PowerLevel;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@@ -15,7 +16,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 = CapabilityHandler.getMaxBlocksPerAxis(player, false); int axisLimit = EffortlessBuildingClient.POWER_LEVEL.getMaxBlocksPerAxis(player);
//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

@@ -3,10 +3,11 @@ package nl.requios.effortlessbuilding.buildmode.buildmodes;
import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.Player;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.world.phys.Vec3; import net.minecraft.world.phys.Vec3;
import nl.requios.effortlessbuilding.EffortlessBuildingClient;
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.capability.CapabilityHandler; import nl.requios.effortlessbuilding.systems.PowerLevel;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@@ -28,7 +29,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 = CapabilityHandler.getBuildModeReach(player); int reach = EffortlessBuildingClient.POWER_LEVEL.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

View File

@@ -1,12 +1,24 @@
package nl.requios.effortlessbuilding.buildmodifier; package nl.requios.effortlessbuilding.buildmodifier;
import net.minecraft.nbt.CompoundTag; 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.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 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 Array extends BaseModifier { public class Array extends BaseModifier {
public Vec3i offset = BlockPos.ZERO; public Vec3i offset = BlockPos.ZERO;

View File

@@ -1,6 +1,7 @@
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

@@ -2,11 +2,13 @@ package nl.requios.effortlessbuilding.buildmodifier;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.nbt.CompoundTag; 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.world.entity.player.Player;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.world.phys.Vec3; import net.minecraft.world.phys.Vec3;
import nl.requios.effortlessbuilding.capability.CapabilityHandler; 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;
@@ -42,7 +44,7 @@ public class Mirror extends BaseModifier {
@Override @Override
public void onPowerLevelChanged(int powerLevel) { public void onPowerLevelChanged(int powerLevel) {
radius = CapabilityHandler.getMaxMirrorRadius(Minecraft.getInstance().player, false); radius = EffortlessBuildingClient.POWER_LEVEL.getMaxMirrorRadius(Minecraft.getInstance().player);
} }
private void performMirrorX(BlockSet blocks, BlockEntry blockEntry) { private void performMirrorX(BlockSet blocks, BlockEntry blockEntry) {

View File

@@ -4,15 +4,23 @@ import net.minecraft.client.Minecraft;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
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.core.BlockPos;
import net.minecraft.util.Mth; import net.minecraft.util.Mth;
import net.minecraft.world.phys.Vec3; import net.minecraft.world.phys.Vec3;
import nl.requios.effortlessbuilding.capability.CapabilityHandler; import net.minecraftforge.items.IItemHandler;
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);
@@ -43,7 +51,7 @@ public class RadialMirror extends BaseModifier {
@Override @Override
public void onPowerLevelChanged(int powerLevel) { public void onPowerLevelChanged(int powerLevel) {
radius = CapabilityHandler.getMaxMirrorRadius(Minecraft.getInstance().player, false); radius = EffortlessBuildingClient.POWER_LEVEL.getMaxMirrorRadius(Minecraft.getInstance().player);
} }
public void performRadialMirror(BlockSet blocks, BlockEntry blockEntry) { public void performRadialMirror(BlockSet blocks, BlockEntry blockEntry) {

View File

@@ -1,137 +0,0 @@
package nl.requios.effortlessbuilding.capability;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.player.Player;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.capabilities.CapabilityManager;
import net.minecraftforge.common.capabilities.CapabilityToken;
import net.minecraftforge.network.PacketDistributor;
import nl.requios.effortlessbuilding.CommonConfig;
import nl.requios.effortlessbuilding.EffortlessBuilding;
import nl.requios.effortlessbuilding.network.PacketHandler;
import nl.requios.effortlessbuilding.network.PowerLevelPacket;
public class CapabilityHandler {
public static final ResourceLocation POWER_LEVEL_CAP = new ResourceLocation(EffortlessBuilding.MODID, "power_level");
public static final Capability<IPowerLevel> POWER_LEVEL_CAPABILITY = CapabilityManager.get(new CapabilityToken<>() {
});
public static void syncToClient(Player player) {
IPowerLevel powerLevel = player.getCapability(CapabilityHandler.POWER_LEVEL_CAPABILITY).orElse(null);
if (powerLevel == null) return; //Should never be null but just to be sure
PacketHandler.INSTANCE.send(PacketDistributor.PLAYER.with(() -> (ServerPlayer) player), new PowerLevelPacket(powerLevel.getPowerLevel()));
}
//Helper methods to reduce boilerplate code
public static boolean canReplaceBlocks(Player player) {
if (player != null) {
IPowerLevel powerLevel = player.getCapability(CapabilityHandler.POWER_LEVEL_CAPABILITY).orElse(null);
if (powerLevel != null) {
return powerLevel.canReplaceBlocks(player);
}
}
return false;
}
public static int getMaxBlocksPerAxis(Player player, boolean nextPowerLevel) {
if (player != null) {
IPowerLevel powerLevel = player.getCapability(CapabilityHandler.POWER_LEVEL_CAPABILITY).orElse(null);
if (powerLevel != null) {
return powerLevel.getMaxBlocksPerAxis(player, nextPowerLevel);
}
}
return CommonConfig.maxBlocksPerAxis.level0.get();
}
public static int getMaxBlocksPlacedAtOnce(Player player, boolean nextPowerLevel) {
if (player != null) {
IPowerLevel powerLevel = player.getCapability(CapabilityHandler.POWER_LEVEL_CAPABILITY).orElse(null);
if (powerLevel != null) {
return powerLevel.getMaxBlocksPlacedAtOnce(player, nextPowerLevel);
}
}
return CommonConfig.maxBlocksPlacedAtOnce.level0.get();
}
public static int getMaxMirrorRadius(Player player, boolean nextPowerLevel) {
if (player != null) {
IPowerLevel powerLevel = player.getCapability(CapabilityHandler.POWER_LEVEL_CAPABILITY).orElse(null);
if (powerLevel != null) {
return powerLevel.getMaxMirrorRadius(player, nextPowerLevel);
}
}
return CommonConfig.maxMirrorRadius.level0.get();
}
public static int getBuildModeReach(Player player) {
if (player != null) {
IPowerLevel powerLevel = player.getCapability(CapabilityHandler.POWER_LEVEL_CAPABILITY).orElse(null);
if (powerLevel != null) {
return powerLevel.getBuildModeReach(player);
}
}
return CommonConfig.maxMirrorRadius.level0.get() + 6;
}
public static int getPlacementReach(Player player, boolean nextPowerLevel) {
if (player != null) {
IPowerLevel powerLevel = player.getCapability(CapabilityHandler.POWER_LEVEL_CAPABILITY).orElse(null);
if (powerLevel != null) {
return powerLevel.getPlacementReach(player, nextPowerLevel);
}
}
return CommonConfig.reach.level0.get();
}
public static int getPowerLevel(Player player) {
if (player != null) {
IPowerLevel powerLevel = player.getCapability(CapabilityHandler.POWER_LEVEL_CAPABILITY).orElse(null);
if (powerLevel != null) {
return powerLevel.getPowerLevel();
}
}
return 0;
}
public static int getNextPowerLevel(Player player) {
if (player != null) {
IPowerLevel powerLevel = player.getCapability(CapabilityHandler.POWER_LEVEL_CAPABILITY).orElse(null);
if (powerLevel != null) {
return powerLevel.getNextPowerLevel();
}
}
return 0;
}
public static boolean canIncreasePowerLevel(Player player) {
if (player != null) {
IPowerLevel powerLevel = player.getCapability(CapabilityHandler.POWER_LEVEL_CAPABILITY).orElse(null);
if (powerLevel != null) {
return powerLevel.canIncreasePowerLevel();
}
}
return false;
}
public static boolean isDisabled(Player player) {
if (player != null) {
IPowerLevel powerLevel = player.getCapability(CapabilityHandler.POWER_LEVEL_CAPABILITY).orElse(null);
if (powerLevel != null) {
return powerLevel.isDisabled(player);
}
}
return false;
}
public static boolean canBreakFar(Player player) {
if (player != null) {
IPowerLevel powerLevel = player.getCapability(CapabilityHandler.POWER_LEVEL_CAPABILITY).orElse(null);
if (powerLevel != null) {
return powerLevel.canBreakFar(player);
}
}
return false;
}
}

View File

@@ -1,38 +0,0 @@
package nl.requios.effortlessbuilding.capability;
import net.minecraft.world.entity.player.Player;
import net.minecraftforge.common.capabilities.AutoRegisterCapability;
@AutoRegisterCapability
public interface IPowerLevel {
int getPowerLevel();
int getNextPowerLevel();
void setPowerLevel(int powerLevel);
boolean canIncreasePowerLevel();
void increasePowerLevel();
int getPlacementReach(Player player, boolean nextPowerLevel);
int getBuildModeReach(Player player);
int getMaxBlocksPlacedAtOnce(Player player, boolean nextPowerLevel);
int getMaxBlocksPerAxis(Player player, boolean nextPowerLevel);
int getMaxMirrorRadius(Player player, boolean nextPowerLevel);
boolean isDisabled(Player player);
boolean canBreakFar(Player player);
boolean canReplaceBlocks(Player player);
}

View File

@@ -1,127 +0,0 @@
package nl.requios.effortlessbuilding.capability;
import net.minecraft.core.Direction;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.entity.player.Player;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.capabilities.ICapabilitySerializable;
import net.minecraftforge.common.util.LazyOptional;
import nl.requios.effortlessbuilding.CommonConfig;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class PowerLevelCapability implements IPowerLevel, ICapabilitySerializable<CompoundTag> {
public static final int MAX_POWER_LEVEL = 3; //Common access
private int powerLevel = 0;
@Override
public int getPowerLevel() {
return this.powerLevel;
}
@Override
public int getNextPowerLevel() {
return Math.min(getPowerLevel() + 1, MAX_POWER_LEVEL);
}
@Override
public void setPowerLevel(int powerLevel) {
this.powerLevel = powerLevel;
}
@Override
public boolean canIncreasePowerLevel() {
return getPowerLevel() < MAX_POWER_LEVEL;
}
@Override
public void increasePowerLevel() {
if (canIncreasePowerLevel()) {
setPowerLevel(getPowerLevel() + 1);
}
}
@Override
public int getPlacementReach(Player player, boolean nextPowerLevel) {
if (player.isCreative()) return CommonConfig.reach.creative.get();
return switch (nextPowerLevel ? getNextPowerLevel() : getPowerLevel()) {
case 1 -> CommonConfig.reach.level1.get();
case 2 -> CommonConfig.reach.level2.get();
case 3 -> CommonConfig.reach.level3.get();
default -> CommonConfig.reach.level0.get();
};
}
//How far away we can detect the second and third click of build modes (distance to player)
@Override
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.
return getPlacementReach(player, false) + 6;
}
@Override
public int getMaxBlocksPlacedAtOnce(Player player, boolean nextPowerLevel) {
if (player.isCreative()) return CommonConfig.maxBlocksPlacedAtOnce.creative.get();
return switch (nextPowerLevel ? getNextPowerLevel() : getPowerLevel()) {
case 1 -> CommonConfig.maxBlocksPlacedAtOnce.level1.get();
case 2 -> CommonConfig.maxBlocksPlacedAtOnce.level2.get();
case 3 -> CommonConfig.maxBlocksPlacedAtOnce.level3.get();
default -> CommonConfig.maxBlocksPlacedAtOnce.level0.get();
};
}
@Override
public int getMaxBlocksPerAxis(Player player, boolean nextPowerLevel) {
if (player.isCreative()) return CommonConfig.maxBlocksPerAxis.creative.get();
return switch (nextPowerLevel ? getNextPowerLevel() : getPowerLevel()) {
case 1 -> CommonConfig.maxBlocksPerAxis.level1.get();
case 2 -> CommonConfig.maxBlocksPerAxis.level2.get();
case 3 -> CommonConfig.maxBlocksPerAxis.level3.get();
default -> CommonConfig.maxBlocksPerAxis.level0.get();
};
}
@Override
public int getMaxMirrorRadius(Player player, boolean nextPowerLevel) {
if (player.isCreative()) return CommonConfig.maxMirrorRadius.creative.get();
return switch (getPowerLevel() + (nextPowerLevel ? 1 : 0)) {
case 1 -> CommonConfig.maxMirrorRadius.level1.get();
case 2 -> CommonConfig.maxMirrorRadius.level2.get();
case 3 -> CommonConfig.maxMirrorRadius.level3.get();
default -> CommonConfig.maxMirrorRadius.level0.get();
};
}
@Override
public boolean isDisabled(Player player) {
return getMaxBlocksPlacedAtOnce(player, false) <= 0 || getMaxBlocksPerAxis(player, false) <= 0;
}
@Override
public boolean canBreakFar(Player player) {
return player.getAbilities().instabuild;
}
@Override
public boolean canReplaceBlocks(Player player) {
return player.getAbilities().instabuild;
}
@Override
public @NotNull <T> LazyOptional<T> getCapability(@NotNull Capability<T> cap, @Nullable Direction side) {
return CapabilityHandler.POWER_LEVEL_CAPABILITY.orEmpty(cap, LazyOptional.of(() -> this));
}
@Override
public CompoundTag serializeNBT() {
CompoundTag tag = new CompoundTag();
tag.putInt("powerLevel", getPowerLevel());
return tag;
}
@Override
public void deserializeNBT(CompoundTag nbt) {
setPowerLevel(nbt.getInt("powerLevel"));
}
}

View File

@@ -7,6 +7,7 @@ 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.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.ItemHandlerHelper;
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,12 +1,69 @@
package nl.requios.effortlessbuilding.create; package nl.requios.effortlessbuilding.create;
import com.mojang.blaze3d.platform.InputConstants;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.screens.Screen;
import org.lwjgl.glfw.GLFW; import org.lwjgl.glfw.GLFW;
import com.mojang.blaze3d.platform.InputConstants;
import net.minecraft.client.KeyMapping;
import net.minecraft.client.Minecraft;
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;
//@EventBusSubscriber(value = Dist.CLIENT, bus = EventBusSubscriber.Bus.MOD)
public class AllKeys { public class AllKeys {
// TOOL_MENU("toolmenu", GLFW.GLFW_KEY_LEFT_ALT),
// ACTIVATE_TOOL("", GLFW.GLFW_KEY_LEFT_CONTROL),
// TOOLBELT("toolbelt", GLFW.GLFW_KEY_LEFT_ALT),
//
// ;
//
// private KeyMapping keybind;
// private String description;
// private int key;
// private boolean modifiable;
//
// private AllKeys(String description, int defaultKey) {
// this.description = Create.ID + ".keyinfo." + description;
// this.key = defaultKey;
// this.modifiable = !description.isEmpty();
// }
//
// @SubscribeEvent
// public static void register(RegisterKeyMappingsEvent event) {
// for (AllKeys key : values()) {
// key.keybind = new KeyMapping(key.description, key.key, Create.NAME);
// if (!key.modifiable)
// continue;
//
// event.register(key.keybind);
// }
// }
//
// public KeyMapping getKeybind() {
// return keybind;
// }
//
// public boolean isPressed() {
// if (!modifiable)
// return isKeyDown(key);
// return keybind.isDown();
// }
//
// public String getBoundKey() {
// return keybind.getTranslatedKeyMessage()
// .getString()
// .toUpperCase();
// }
//
// public int getBoundCode() {
// return keybind.getKey()
// .getValue();
// }
public static boolean isKeyDown(int key) { public static boolean isKeyDown(int key) {
return InputConstants.isKeyDown(Minecraft.getInstance() return InputConstants.isKeyDown(Minecraft.getInstance()
.getWindow() .getWindow()

View File

@@ -1,10 +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 implements BindableTexture { public enum AllSpecialTextures {
BLANK("blank.png"), BLANK("blank.png"),
CHECKERED("checkerboard.png"), CHECKERED("checkerboard.png"),
@@ -19,7 +19,7 @@ public enum AllSpecialTextures implements BindableTexture {
public static final String ASSET_PATH = "textures/special/"; public static final String ASSET_PATH = "textures/special/";
private ResourceLocation location; private ResourceLocation location;
AllSpecialTextures(String filename) { private AllSpecialTextures(String filename) {
location = Create.asResource(ASSET_PATH + filename); location = Create.asResource(ASSET_PATH + filename);
} }

View File

@@ -1,10 +1,12 @@
package nl.requios.effortlessbuilding.create; package nl.requios.effortlessbuilding.create;
import net.createmod.catnip.render.SuperByteBufferCache; import nl.requios.effortlessbuilding.create.foundation.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.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,7 +1,12 @@
package nl.requios.effortlessbuilding.create; 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.api.distmarker.Dist;
import net.minecraftforge.event.TickEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.Mod;
import nl.requios.effortlessbuilding.create.foundation.utility.Color;
@Mod.EventBusSubscriber(Dist.CLIENT) @Mod.EventBusSubscriber(Dist.CLIENT)
public class CreateClientTest { public class CreateClientTest {

View File

@@ -1,39 +0,0 @@
package nl.requios.effortlessbuilding.create.events;
import net.minecraft.world.level.LevelAccessor;
import net.minecraftforge.event.level.LevelEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
import nl.requios.effortlessbuilding.create.foundation.utility.WorldAttached;
@EventBusSubscriber
public class CommonEvents {
@SubscribeEvent
public static void onUnloadWorld(LevelEvent.Unload event) {
LevelAccessor world = event.getLevel();
WorldAttached.invalidateWorld(world);
}
@EventBusSubscriber(bus = EventBusSubscriber.Bus.MOD)
public static class ModBusEvents {
// @SubscribeEvent
// public static void addPackFinders(AddPackFindersEvent event) {
// if (event.getPackType() == PackType.CLIENT_RESOURCES) {
// IModFileInfo modFileInfo = ModList.get().getModFileById(Create.ID);
// if (modFileInfo == null) {
// Create.LOGGER.error("Could not find Create mod file info; built-in resource packs will be missing!");
// return;
// }
// IModFile modFile = modFileInfo.getFile();
// event.addRepositorySource((consumer, constructor) -> {
// consumer.accept(Pack.create(Create.asResource("legacy_copper").toString(), false, () -> new ModFilePackResources("Create Legacy Copper", modFile, "resourcepacks/legacy_copper"), constructor, Pack.Position.TOP, PackSource.DEFAULT));
// });
// }
// }
}
}

View File

@@ -1,6 +1,9 @@
package nl.requios.effortlessbuilding.create.foundation; package nl.requios.effortlessbuilding.create.foundation;
import nl.requios.effortlessbuilding.create.CreateClient;
//import nl.requios.effortlessbuilding.create.foundation.sound.SoundScapes;
import nl.requios.effortlessbuilding.create.foundation.utility.LangNumberFormat; import nl.requios.effortlessbuilding.create.foundation.utility.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;
@@ -8,7 +11,7 @@ public class ClientResourceReloadListener implements ResourceManagerReloadListen
@Override @Override
public void onResourceManagerReload(ResourceManager resourceManager) { public void onResourceManagerReload(ResourceManager resourceManager) {
// CreateClient.invalidateRenderers(); CreateClient.invalidateRenderers();
// SoundScapes.invalidateAll(); // SoundScapes.invalidateAll();
LangNumberFormat.numberFormat.update(); LangNumberFormat.numberFormat.update();
} }

View File

@@ -1,10 +1,10 @@
package nl.requios.effortlessbuilding.create.foundation; package nl.requios.effortlessbuilding.create.foundation;
import java.nio.file.Path;
import net.minecraftforge.forgespi.locating.IModFile; import net.minecraftforge.forgespi.locating.IModFile;
import net.minecraftforge.resource.PathPackResources; import net.minecraftforge.resource.PathPackResources;
import java.nio.file.Path;
public class ModFilePackResources extends PathPackResources { public class ModFilePackResources extends PathPackResources {
protected final IModFile modFile; protected final IModFile modFile;
protected final String sourcePath; protected final String sourcePath;

View File

@@ -1,6 +1,6 @@
package nl.requios.effortlessbuilding.create.foundation.block.render; package nl.requios.effortlessbuilding.create.foundation.block.render;
import net.createmod.catnip.render.StitchedSprite; import com.jozufozu.flywheel.core.StitchedSprite;
import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;

View File

@@ -1,10 +1,11 @@
package nl.requios.effortlessbuilding.create.events; package nl.requios.effortlessbuilding.create.foundation.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.outliner.Outliner;
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.item.Item;
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.minecraftforge.api.distmarker.Dist;
@@ -12,16 +13,17 @@ import net.minecraftforge.client.event.RenderLevelStageEvent;
import net.minecraftforge.client.event.ViewportEvent; import net.minecraftforge.client.event.ViewportEvent;
import net.minecraftforge.event.TickEvent; import net.minecraftforge.event.TickEvent;
import net.minecraftforge.event.TickEvent.ClientTickEvent; import net.minecraftforge.event.TickEvent.ClientTickEvent;
import net.minecraftforge.event.entity.player.ItemTooltipEvent;
import net.minecraftforge.event.level.LevelEvent; import net.minecraftforge.event.level.LevelEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod.EventBusSubscriber; 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.item.TooltipModifier;
import nl.requios.effortlessbuilding.create.foundation.render.SuperRenderTypeBuffer;
import nl.requios.effortlessbuilding.create.foundation.utility.AnimationTickHolder; 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; import nl.requios.effortlessbuilding.create.foundation.utility.worldWrappers.WrappedClientWorld;
import net.createmod.catnip.render.DefaultSuperRenderTypeBuffer;
import net.createmod.catnip.render.SuperRenderTypeBuffer;
@EventBusSubscriber(Dist.CLIENT) @EventBusSubscriber(Dist.CLIENT)
public class ClientEvents { public class ClientEvents {
@@ -36,7 +38,7 @@ public class ClientEvents {
AnimationTickHolder.tick(); AnimationTickHolder.tick();
CreateClient.GHOST_BLOCKS.tickGhosts(); CreateClient.GHOST_BLOCKS.tickGhosts();
// Outliner.getInstance().tickOutlines(); CreateClient.OUTLINER.tickOutlines();
CameraAngleAnimationService.tick(); CameraAngleAnimationService.tick();
} }
@@ -60,23 +62,21 @@ public class ClientEvents {
@SubscribeEvent @SubscribeEvent
public static void onRenderWorld(RenderLevelStageEvent event) { public static void onRenderWorld(RenderLevelStageEvent event) {
if(event.getStage() != RenderLevelStageEvent.Stage.AFTER_CUTOUT_BLOCKS) return; if (event.getStage() != RenderLevelStageEvent.Stage.AFTER_PARTICLES)
return;
Vec3 cameraPos = Minecraft.getInstance().gameRenderer.getMainCamera()
.getPosition();
float pt = AnimationTickHolder.getPartialTicks();
PoseStack ms = event.getPoseStack(); PoseStack ms = event.getPoseStack();
ms.pushPose(); ms.pushPose();
ms.translate(-cameraPos.x(), -cameraPos.y(), -cameraPos.z()); SuperRenderTypeBuffer buffer = SuperRenderTypeBuffer.getInstance();
SuperRenderTypeBuffer buffer = DefaultSuperRenderTypeBuffer.getInstance(); float partialTicks = AnimationTickHolder.getPartialTicks();
Vec3 camera = Minecraft.getInstance().gameRenderer.getMainCamera()
.getPosition();
CreateClient.GHOST_BLOCKS.renderAll(ms, buffer); CreateClient.GHOST_BLOCKS.renderAll(ms, buffer, camera);
CreateClient.OUTLINER.renderOutlines(ms, buffer, camera, partialTicks);
// Outliner.getInstance().renderOutlines(ms, buffer, pt);
buffer.draw(); buffer.draw();
RenderSystem.enableCull(); RenderSystem.enableCull();
ms.popPose(); ms.popPose();
} }
@@ -91,6 +91,20 @@ public class ClientEvents {
event.setPitch(CameraAngleAnimationService.getPitch(partialTicks)); event.setPitch(CameraAngleAnimationService.getPitch(partialTicks));
} }
@SubscribeEvent
public static void addToItemTooltip(ItemTooltipEvent event) {
// if (!AllConfigs.client().tooltips.get())
// return;
if (event.getEntity() == null)
return;
Item item = event.getItemStack().getItem();
TooltipModifier modifier = TooltipModifier.REGISTRY.get(item);
if (modifier != null && modifier != TooltipModifier.EMPTY) {
modifier.modify(event);
}
}
public static boolean isGameActive() { public static boolean isGameActive() {
return !(Minecraft.getInstance().level == null || Minecraft.getInstance().player == null); return !(Minecraft.getInstance().level == null || Minecraft.getInstance().player == null);
} }

View File

@@ -0,0 +1,18 @@
package nl.requios.effortlessbuilding.create.foundation.events;
import net.minecraft.world.level.LevelAccessor;
import net.minecraftforge.event.level.LevelEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
import nl.requios.effortlessbuilding.create.foundation.utility.WorldAttached;
@EventBusSubscriber
public class CommonEvents {
@SubscribeEvent
public static void onUnloadWorld(LevelEvent.Unload event) {
LevelAccessor world = event.getLevel();
WorldAttached.invalidateWorld(world);
}
}

View File

@@ -1,7 +1,13 @@
package nl.requios.effortlessbuilding.create.foundation.gui; package nl.requios.effortlessbuilding.create.foundation.gui;
import java.util.Collection;
import java.util.List;
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 nl.requios.effortlessbuilding.create.foundation.utility.Components;
import net.minecraft.client.gui.GuiGraphics; 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.EditBox; import net.minecraft.client.gui.components.EditBox;
@@ -12,12 +18,6 @@ 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.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.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 java.util.Collection;
import java.util.List;
@OnlyIn(Dist.CLIENT) @OnlyIn(Dist.CLIENT)
public abstract class AbstractSimiScreen extends Screen { public abstract class AbstractSimiScreen extends Screen {
@@ -157,11 +157,6 @@ public abstract class AbstractSimiScreen extends Screen {
int tty = simiWidget.lockedTooltipY == -1 ? mouseY : simiWidget.lockedTooltipY + simiWidget.getY(); int tty = simiWidget.lockedTooltipY == -1 ? mouseY : simiWidget.lockedTooltipY + simiWidget.getY();
graphics.renderComponentTooltip(font, tooltip, ttx, tty); graphics.renderComponentTooltip(font, tooltip, ttx, tty);
} }
//Added
if (widget instanceof ModifiersScreenList list) {
list.renderWindowForeground(graphics, mouseX, mouseY, partialTicks);
}
} }
} }

View File

@@ -1,16 +1,164 @@
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 net.minecraft.client.gui.GuiGraphics;
import net.minecraft.resources.ResourceLocation;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import nl.requios.effortlessbuilding.create.Create; import nl.requios.effortlessbuilding.create.Create;
import nl.requios.effortlessbuilding.create.foundation.gui.element.ScreenElement; import nl.requios.effortlessbuilding.create.foundation.gui.element.ScreenElement;
import nl.requios.effortlessbuilding.create.foundation.utility.Color; import nl.requios.effortlessbuilding.create.foundation.utility.Color;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.resources.ResourceLocation;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
public enum AllGuiTextures implements ScreenElement { public enum AllGuiTextures implements ScreenElement {
// Inventories
// PLAYER_INVENTORY("player_inventory", 176, 108),
// WAND_OF_SYMMETRY("curiosities", 0, 131, 188, 101),
// BLOCKZAPPER("curiosities", 0, 99, 214, 97),
// TERRAINZAPPER("curiosities", 234, 103),
// TERRAINZAPPER_INACTIVE_PARAM("curiosities", 238, 0, 18, 18),
//
// LOGO("logo", 256, 256),
// CURSEFORGE_LOGO("platform_icons/curseforge", 256, 256),
// MODRINTH_LOGO("platform_icons/modrinth", 256, 256),
//
// SCHEMATIC("schematics", 192, 121),
// SCHEMATIC_SLOT("widgets", 54, 0, 16, 16),
// SCHEMATIC_PROMPT("schematics_2", 213, 77),
// HUD_BACKGROUND("overlay", 0, 0, 16, 16),
//
// SCHEMATIC_TABLE("schematics", 0, 121, 214, 83),
// SCHEMATIC_TABLE_PROGRESS("schematics", 0, 204, 84, 16),
//
// SCHEMATICANNON_TOP("schematics_2", 0, 77, 213, 42),
// SCHEMATICANNON_BOTTOM("schematics_2", 0, 119, 213, 99),
// SCHEMATICANNON_PROGRESS("schematics_2", 76, 239, 114, 16),
// SCHEMATICANNON_CHECKLIST_PROGRESS("schematics_2", 191, 240, 16, 14),
// SCHEMATICANNON_HIGHLIGHT("schematics_2", 1, 229, 26, 26),
// SCHEMATICANNON_FUEL("schematics_2", 28, 222, 47, 16),
// SCHEMATICANNON_FUEL_CREATIVE("schematics_2", 28, 239, 47, 16),
//
// STOCKSWITCH("logistics", 182, 95),
// STOCKSWITCH_ARROW_UP("logistics", 191, 0, 7, 24),
// STOCKSWITCH_ARROW_DOWN("logistics", 198, 0, 7, 24),
// STOCKSWITCH_CURSOR("logistics", 206, 0, 7, 16),
// STOCKSWITCH_INTERVAL("logistics", 0, 95, 100, 18),
// STOCKSWITCH_UNPOWERED_LANE("logistics", 37, 20, 100, 18),
// STOCKSWITCH_POWERED_LANE("logistics", 37, 42, 100, 18),
//
// FILTER("filters", 214, 99),
// ATTRIBUTE_FILTER("filters", 0, 99, 241, 85),
//
// TOOLBOX("toolbox", 188, 171),
// TOOLBELT_SLOT("minecraft", "widgets", 24, 23, 22, 22),
// TOOLBELT_SLOT_HIGHLIGHT("minecraft", "widgets", 0, 22, 24, 24),
// TOOLBELT_MAIN_SLOT("widgets", 0, 97, 24, 24),
// TOOLBELT_EMPTY_SLOT("widgets", 27, 98, 22, 22),
// TOOLBELT_INACTIVE_SLOT("widgets", 52, 98, 22, 22),
//
// TOOLBELT_HOTBAR_OFF("widgets", 0, 130, 20, 24),
// TOOLBELT_HOTBAR_ON("widgets", 20, 130, 20, 24),
// TOOLBELT_SELECTED_OFF("widgets", 0, 155, 22, 22),
// TOOLBELT_SELECTED_ON("widgets", 22, 155, 22, 22),
//
// SEQUENCER("sequencer", 173, 161),
// SEQUENCER_INSTRUCTION("sequencer", 0, 16, 162, 22),
// SEQUENCER_DELAY("sequencer", 0, 60, 162, 22),
// SEQUENCER_END("sequencer", 0, 82, 162, 22),
// SEQUENCER_EMPTY("sequencer", 0, 104, 162, 22),
// SEQUENCER_AWAIT("sequencer", 0, 162, 162, 22),
//
// LINKED_CONTROLLER("curiosities_2", 179, 109),
// BLUEPRINT("curiosities_2", 0, 109, 179, 109),
//
// CLIPBOARD("clipboard", 0, 0, 256, 256),
//
// DATA_GATHERER("display_link", 235, 162),
// DATA_AREA_START("display_link", 0, 163, 2, 18),
// DATA_AREA_SPEECH("display_link", 8, 163, 5, 18),
// DATA_AREA("display_link", 3, 163, 1, 18),
// DATA_AREA_END("display_link", 5, 163, 2, 18),
//
// SCHEDULE("schedule", 256, 226),
// SCHEDULE_CARD_DARK("schedule", 5, 233, 1, 1),
// SCHEDULE_CARD_MEDIUM("schedule", 6, 233, 1, 1),
// SCHEDULE_CARD_LIGHT("schedule", 7, 233, 1, 1),
// SCHEDULE_CARD_MOVE_UP("schedule", 51, 230, 12, 12),
// SCHEDULE_CARD_MOVE_DOWN("schedule", 65, 230, 12, 12),
// SCHEDULE_CARD_REMOVE("schedule", 51, 243, 12, 12),
// SCHEDULE_CARD_DUPLICATE("schedule", 65, 243, 12, 12),
// SCHEDULE_CARD_NEW("schedule", 79, 239, 16, 16),
// SCHEDULE_CONDITION_NEW("schedule", 96, 239, 19, 16),
// SCHEDULE_CONDITION_LEFT("schedule", 116, 239, 6, 16),
// SCHEDULE_CONDITION_LEFT_CLEAN("schedule", 147, 239, 2, 16),
// SCHEDULE_CONDITION_MIDDLE("schedule", 123, 239, 1, 16),
// SCHEDULE_CONDITION_ITEM("schedule", 125, 239, 18, 16),
// SCHEDULE_CONDITION_RIGHT("schedule", 144, 239, 2, 16),
// SCHEDULE_CONDITION_APPEND("schedule", 150, 245, 10, 10),
// SCHEDULE_SCROLL_LEFT("schedule", 161, 247, 4, 8),
// SCHEDULE_SCROLL_RIGHT("schedule", 166, 247, 4, 8),
// SCHEDULE_STRIP_DARK("schedule", 5, 235, 3, 1),
// SCHEDULE_STRIP_LIGHT("schedule", 5, 237, 3, 1),
// SCHEDULE_STRIP_WAIT("schedule", 1, 239, 11, 16),
// SCHEDULE_STRIP_TRAVEL("schedule", 12, 239, 11, 16),
// SCHEDULE_STRIP_DOTTED("schedule", 23, 239, 11, 16),
// SCHEDULE_STRIP_END("schedule", 34, 239, 11, 16),
// SCHEDULE_STRIP_ACTION("schedule", 209, 239, 11, 16),
// SCHEDULE_EDITOR("schedule_2", 256, 89),
// SCHEDULE_EDITOR_ADDITIONAL_SLOT("schedule_2", 55, 47, 32, 18),
// SCHEDULE_EDITOR_INACTIVE_SLOT("schedule_2", 0, 91, 18, 18),
// SCHEDULE_POINTER("schedule", 185, 239, 21, 16),
// SCHEDULE_POINTER_OFFSCREEN("schedule", 171, 239, 13, 16),
//
// STATION("schedule_2", 0, 111, 200, 127),
// STATION_ASSEMBLING("assemble", 200, 178),
// STATION_TEXTBOX_TOP("assemble", 1, 179, 150, 18),
// STATION_TEXTBOX_MIDDLE("assemble", 1, 198, 150, 1),
// STATION_TEXTBOX_BOTTOM("assemble", 1, 200, 150, 4),
// STATION_TEXTBOX_SPEECH("assemble", 152, 179, 8, 6),
// STATION_EDIT_NAME("schedule_2", 0, 239, 13, 13),
// STATION_EDIT_TRAIN_NAME("schedule_2", 89, 239, 13, 13),
// I_NEW_TRAIN("schedule_2", 14, 239, 24, 16),
// I_DISASSEMBLE_TRAIN("schedule_2", 39, 239, 24, 16),
// I_ASSEMBLE_TRAIN("schedule_2", 64, 239, 24, 16),
//
// ELEVATOR_CONTACT("display_link", 20, 172, 233, 82),
//
// BRASS_FRAME_TL("value_settings", 65, 9, 4, 4),
// BRASS_FRAME_TR("value_settings", 70, 9, 4, 4),
// BRASS_FRAME_BL("value_settings", 65, 19, 4, 4),
// BRASS_FRAME_BR("value_settings", 70, 19, 4, 4),
// BRASS_FRAME_LEFT("value_settings", 65, 14, 3, 4),
// BRASS_FRAME_RIGHT("value_settings", 71, 14, 3, 4),
// BRASS_FRAME_TOP("value_settings", 0, 24, 256, 3),
// BRASS_FRAME_BOTTOM("value_settings", 0, 27, 256, 3),
//
// VALUE_SETTINGS_MILESTONE("value_settings", 0, 0, 7, 8),
// VALUE_SETTINGS_WIDE_MILESTONE("value_settings", 75, 14, 13, 8),
// VALUE_SETTINGS_BAR("value_settings", 7, 0, 249, 8),
// VALUE_SETTINGS_BAR_BG("value_settings", 75, 9, 1, 1),
// VALUE_SETTINGS_OUTER_BG("value_settings", 80, 9, 1, 1),
// VALUE_SETTINGS_CURSOR_LEFT("value_settings", 0, 9, 3, 14),
// VALUE_SETTINGS_CURSOR("value_settings", 4, 9, 56, 14),
// VALUE_SETTINGS_CURSOR_RIGHT("value_settings", 61, 9, 3, 14),
// VALUE_SETTINGS_CURSOR_ICON("value_settings", 0, 44, 22, 20),
// VALUE_SETTINGS_LABEL_BG("value_settings", 0, 31, 81, 11),
//
// // JEI
// JEI_SLOT("jei/widgets", 18, 18),
// JEI_CHANCE_SLOT("jei/widgets", 20, 156, 18, 18),
// JEI_CATALYST_SLOT("jei/widgets", 0, 156, 18, 18),
// JEI_ARROW("jei/widgets", 19, 10, 42, 10),
// JEI_LONG_ARROW("jei/widgets", 19, 0, 71, 10),
// JEI_DOWN_ARROW("jei/widgets", 0, 21, 18, 14),
// JEI_LIGHT("jei/widgets", 0, 42, 52, 11),
// JEI_QUESTION_MARK("jei/widgets", 0, 178, 12, 16),
// JEI_SHADOW("jei/widgets", 0, 56, 52, 11),
// BLOCKZAPPER_UPGRADE_RECIPE("jei/widgets", 0, 75, 144, 66),
// JEI_HEAT_BAR("jei/widgets", 0, 201, 169, 19),
// JEI_NO_HEAT_BAR("jei/widgets", 0, 221, 169, 19),
// Widgets // Widgets
BUTTON("widgets", 18, 18), BUTTON("widgets", 18, 18),
BUTTON_HOVER("widgets", 18, 0, 18, 18), BUTTON_HOVER("widgets", 18, 0, 18, 18),
@@ -29,15 +177,21 @@ 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),
TRAIN_HUD_THROTTLE_POINTER("widgets", 0, 209, 6, 9), // TRAIN_HUD_THROTTLE_POINTER("widgets", 0, 209, 6, 9),
TRAIN_HUD_FRAME("widgets", 0, 200, 186, 7), // TRAIN_HUD_FRAME("widgets", 0, 200, 186, 7),
TRAIN_HUD_DIRECTION("widgets", 77, 165, 28, 20), // TRAIN_HUD_DIRECTION("widgets", 77, 165, 28, 20),
TRAIN_PROMPT_L("widgets", 8, 209, 3, 16), // TRAIN_PROMPT_L("widgets", 8, 209, 3, 16),
TRAIN_PROMPT_R("widgets", 11, 209, 3, 16), // TRAIN_PROMPT_R("widgets", 11, 209, 3, 16),
TRAIN_PROMPT("widgets", 0, 230, 256, 16), // TRAIN_PROMPT("widgets", 0, 230, 256, 16),
// PlacementIndicator
// PLACEMENT_INDICATOR_SHEET("placement_indicator", 0, 0, 16, 256),
// ComputerCraft
// COMPUTER("computer", 200, 102);
; ;

View File

@@ -1,8 +1,15 @@
package nl.requios.effortlessbuilding.create.foundation.gui; package nl.requios.effortlessbuilding.create.foundation.gui;
import org.joml.Matrix4f;
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 nl.requios.effortlessbuilding.create.Create;
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;
import net.minecraft.client.gui.GuiGraphics; 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;
@@ -11,15 +18,10 @@ 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.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.api.distmarker.OnlyIn;
import nl.requios.effortlessbuilding.create.Create;
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;
import org.joml.Matrix4f;
public class AllIcons implements ScreenElement { public class AllIcons implements ScreenElement {
public static final ResourceLocation ICON_ATLAS = Create.asResource("textures/gui/create_icons.png"); public static final ResourceLocation ICON_ATLAS = Create.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;
@@ -103,6 +105,10 @@ public class AllIcons implements ScreenElement {
I_ADD_INVERTED_ATTRIBUTE = next(), I_ADD_INVERTED_ATTRIBUTE = next(),
I_FLIP = next(), I_FLIP = next(),
I_ROLLER_PAVE = next(),
I_ROLLER_FILL = next(),
I_ROLLER_WIDE_FILL = next(),
I_PLAY = newRow(), I_PLAY = newRow(),
I_PAUSE = next(), I_PAUSE = next(),
@@ -122,9 +128,14 @@ public class AllIcons implements ScreenElement {
I_PATTERN_CHANCE_75 = next(), I_PATTERN_CHANCE_75 = next(),
I_FOLLOW_DIAGONAL = next(), I_FOLLOW_DIAGONAL = next(),
I_FOLLOW_MATERIAL = next(), I_FOLLOW_MATERIAL = next(),
I_CLEAR_CHECKED = next(),
I_SCHEMATIC = newRow(), I_SCHEMATIC = newRow(),
I_SEQ_REPEAT = next(), I_SEQ_REPEAT = next(),
VALUE_BOX_HOVER_6PX = next(),
VALUE_BOX_HOVER_4PX = next(),
VALUE_BOX_HOVER_8PX = next(),
I_MTD_LEFT = newRow(), I_MTD_LEFT = newRow(),
I_MTD_CLOSE = next(), I_MTD_CLOSE = next(),

View File

@@ -1,21 +1,24 @@
package nl.requios.effortlessbuilding.create.foundation.gui; package nl.requios.effortlessbuilding.create.foundation.gui;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
import javax.annotation.Nonnull;
import org.lwjgl.opengl.GL30;
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 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.Minecraft;
import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.gui.screens.Screen; import net.minecraft.client.gui.screens.Screen;
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 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 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 { public class ConfirmationScreen extends AbstractSimiScreen {

View File

@@ -0,0 +1,115 @@
package nl.requios.effortlessbuilding.create.foundation.gui;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
import nl.requios.effortlessbuilding.create.foundation.gui.widget.ScrollInput;
import nl.requios.effortlessbuilding.create.foundation.gui.widget.TooltipArea;
import nl.requios.effortlessbuilding.create.foundation.utility.Couple;
import nl.requios.effortlessbuilding.create.foundation.utility.Pair;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.gui.components.AbstractWidget;
import net.minecraft.client.gui.components.EditBox;
import net.minecraft.client.gui.components.Renderable;
import net.minecraft.client.gui.components.events.GuiEventListener;
import net.minecraft.client.gui.narration.NarratableEntry;
import net.minecraft.nbt.CompoundTag;
public class ModularGuiLine {
List<Pair<AbstractWidget, String>> widgets;
List<Couple<Integer>> customBoxes;
boolean speechBubble;
public ModularGuiLine() {
widgets = new ArrayList<>();
customBoxes = new ArrayList<>();
speechBubble = false;
}
public void renderWidgetBG(int guiLeft, GuiGraphics graphics) {
boolean first = true;
if (!customBoxes.isEmpty()) {
for (Couple<Integer> couple : customBoxes) {
int x = couple.getFirst() + guiLeft;
int width = couple.getSecond();
box(graphics, x, width, first & speechBubble);
first = false;
}
return;
}
for (Pair<AbstractWidget, String> pair : widgets) {
if (pair.getSecond()
.equals("Dummy"))
continue;
AbstractWidget aw = pair.getFirst();
int x = aw.getX();
int width = aw.getWidth();
if (aw instanceof EditBox) {
x -= 5;
width += 9;
}
box(graphics, x, width, first & speechBubble);
first = false;
}
}
private void box(GuiGraphics graphics, int x, int width, boolean b) {
// UIRenderHelper.drawStretched(graphics, x, 0, width, 18, 0, AllGuiTextures.DATA_AREA);
// if (b)
// AllGuiTextures.DATA_AREA_SPEECH.render(graphics, x - 3, 0);
// else
// AllGuiTextures.DATA_AREA_START.render(graphics, x, 0);
// AllGuiTextures.DATA_AREA_END.render(graphics, x + width - 2, 0);
}
public void saveValues(CompoundTag data) {
for (Pair<AbstractWidget, String> pair : widgets) {
AbstractWidget w = pair.getFirst();
String key = pair.getSecond();
if (w instanceof EditBox eb)
data.putString(key, eb.getValue());
if (w instanceof ScrollInput si)
data.putInt(key, si.getState());
}
}
@SuppressWarnings("unchecked")
public <T extends GuiEventListener & Renderable & NarratableEntry> void loadValues(CompoundTag data,
Consumer<T> addRenderable, Consumer<T> addRenderableOnly) {
for (Pair<AbstractWidget, String> pair : widgets) {
AbstractWidget w = pair.getFirst();
String key = pair.getSecond();
if (w instanceof EditBox eb)
eb.setValue(data.getString(key));
if (w instanceof ScrollInput si)
si.setState(data.getInt(key));
if (w instanceof TooltipArea)
addRenderableOnly.accept((T) w);
else
addRenderable.accept((T) w);
}
}
public void forEach(Consumer<GuiEventListener> callback) {
widgets.forEach(p -> callback.accept(p.getFirst()));
}
public void clear() {
widgets.clear();
customBoxes.clear();
}
public void add(Pair<AbstractWidget, String> pair) {
widgets.add(pair);
}
}

View File

@@ -0,0 +1,91 @@
package nl.requios.effortlessbuilding.create.foundation.gui;
import java.util.function.BiConsumer;
import nl.requios.effortlessbuilding.create.foundation.gui.widget.Label;
import nl.requios.effortlessbuilding.create.foundation.gui.widget.ScrollInput;
import nl.requios.effortlessbuilding.create.foundation.gui.widget.SelectionScrollInput;
import nl.requios.effortlessbuilding.create.foundation.gui.widget.TooltipArea;
import nl.requios.effortlessbuilding.create.foundation.utility.Components;
import nl.requios.effortlessbuilding.create.foundation.utility.Couple;
import nl.requios.effortlessbuilding.create.foundation.utility.Pair;
import net.minecraft.client.gui.Font;
import net.minecraft.client.gui.components.EditBox;
public class ModularGuiLineBuilder {
private ModularGuiLine target;
private Font font;
private int x;
private int y;
public ModularGuiLineBuilder(Font font, ModularGuiLine target, int x, int y) {
this.font = font;
this.target = target;
this.x = x;
this.y = y;
}
public ModularGuiLineBuilder addScrollInput(int x, int width, BiConsumer<ScrollInput, Label> inputTransform,
String dataKey) {
ScrollInput input = new ScrollInput(x + this.x, y - 4, width, 18);
addScrollInput(input, inputTransform, dataKey);
return this;
}
public ModularGuiLineBuilder addSelectionScrollInput(int x, int width,
BiConsumer<SelectionScrollInput, Label> inputTransform, String dataKey) {
SelectionScrollInput input = new SelectionScrollInput(x + this.x, y - 4, width, 18);
addScrollInput(input, inputTransform, dataKey);
return this;
}
public ModularGuiLineBuilder customArea(int x, int width) {
target.customBoxes.add(Couple.create(x, width));
return this;
}
public ModularGuiLineBuilder speechBubble() {
target.speechBubble = true;
return this;
}
private <T extends ScrollInput> void addScrollInput(T input, BiConsumer<T, Label> inputTransform, String dataKey) {
Label label = new Label(input.getX() + 5, y, Components.immutableEmpty());
label.withShadow();
inputTransform.accept(input, label);
input.writingTo(label);
target.add(Pair.of(label, "Dummy"));
target.add(Pair.of(input, dataKey));
}
public ModularGuiLineBuilder addIntegerTextInput(int x, int width, BiConsumer<EditBox, TooltipArea> inputTransform,
String dataKey) {
return addTextInput(x, width, inputTransform.andThen((editBox, $) -> editBox.setFilter(s -> {
if (s.isEmpty())
return true;
try {
Integer.parseInt(s);
return true;
} catch (NumberFormatException e) {
return false;
}
})), dataKey);
}
public ModularGuiLineBuilder addTextInput(int x, int width, BiConsumer<EditBox, TooltipArea> inputTransform,
String dataKey) {
EditBox input = new EditBox(font, x + this.x + 5, y, width - 9, 8, Components.immutableEmpty());
input.setBordered(false);
input.setTextColor(0xffffff);
input.setFocused(false);
input.mouseClicked(0, 0, 0);
TooltipArea tooltipArea = new TooltipArea(this.x + x, y - 4, width, 18);
inputTransform.accept(input, tooltipArea);
target.add(Pair.of(input, dataKey));
target.add(Pair.of(tooltipArea, "Dummy"));
return this;
}
}

View File

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

View File

@@ -1,5 +1,9 @@
package nl.requios.effortlessbuilding.create.foundation.gui; package nl.requios.effortlessbuilding.create.foundation.gui;
import org.joml.Matrix4f;
import org.lwjgl.opengl.GL20;
import org.lwjgl.opengl.GL30;
import com.mojang.blaze3d.pipeline.RenderTarget; import com.mojang.blaze3d.pipeline.RenderTarget;
import com.mojang.blaze3d.platform.GlConst; import com.mojang.blaze3d.platform.GlConst;
import com.mojang.blaze3d.platform.GlStateManager; import com.mojang.blaze3d.platform.GlStateManager;
@@ -11,14 +15,12 @@ import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.Tesselator; import com.mojang.blaze3d.vertex.Tesselator;
import com.mojang.blaze3d.vertex.VertexFormat; import com.mojang.blaze3d.vertex.VertexFormat;
import com.mojang.math.Axis; import com.mojang.math.Axis;
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.Minecraft;
import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.renderer.GameRenderer; import net.minecraft.client.renderer.GameRenderer;
import nl.requios.effortlessbuilding.create.foundation.utility.Color;
import nl.requios.effortlessbuilding.create.foundation.utility.Couple;
import org.joml.Matrix4f;
import org.lwjgl.opengl.GL20;
import org.lwjgl.opengl.GL30;
public class UIRenderHelper { public class UIRenderHelper {
@@ -110,21 +112,21 @@ public class UIRenderHelper {
} }
/** /**
* @see #angledGradient(GuiGraphics, float, int, int, int, int, int, Color, Color) * @see #angledGradient(MatrixStack, float, int, int, int, int, int, Color, Color)
*/ */
public static void angledGradient(GuiGraphics graphics, float angle, int x, int y, int breadth, int length, Couple<Color> c) { public static void angledGradient(GuiGraphics graphics, float angle, int x, int y, int breadth, int length, Couple<Color> c) {
angledGradient(graphics, angle, x, y, 0, breadth, length, c); angledGradient(graphics, angle, x, y, 0, breadth, length, c);
} }
/** /**
* @see #angledGradient(GuiGraphics, float, int, int, int, int, int, Color, Color) * @see #angledGradient(MatrixStack, float, int, int, int, int, int, Color, Color)
*/ */
public static void angledGradient(GuiGraphics graphics, float angle, int x, int y, int z, int breadth, int length, Couple<Color> c) { public static void angledGradient(GuiGraphics graphics, float angle, int x, int y, int z, int breadth, int length, Couple<Color> c) {
angledGradient(graphics, angle, x, y, z, breadth, length, c.getFirst(), c.getSecond()); angledGradient(graphics, angle, x, y, z, breadth, length, c.getFirst(), c.getSecond());
} }
/** /**
* @see #angledGradient(GuiGraphics, float, int, int, int, int, int, Color, Color) * @see #angledGradient(MatrixStack, float, int, int, int, int, int, Color, Color)
*/ */
public static void angledGradient(GuiGraphics graphics, float angle, int x, int y, int breadth, int length, Color color1, Color color2) { public static void angledGradient(GuiGraphics graphics, float angle, int x, int y, int breadth, int length, Color color1, Color color2) {
angledGradient(graphics, angle, x, y, 0, breadth, length, color1, color2); angledGradient(graphics, angle, x, y, 0, breadth, length, color1, color2);

View File

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

View File

@@ -1,16 +1,18 @@
package nl.requios.effortlessbuilding.create.foundation.gui.element; package nl.requios.effortlessbuilding.create.foundation.gui.element;
import org.joml.Matrix4f;
import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.BufferBuilder; import com.mojang.blaze3d.vertex.BufferBuilder;
import com.mojang.blaze3d.vertex.DefaultVertexFormat; import com.mojang.blaze3d.vertex.DefaultVertexFormat;
import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.Tesselator; import com.mojang.blaze3d.vertex.Tesselator;
import com.mojang.blaze3d.vertex.VertexFormat; import com.mojang.blaze3d.vertex.VertexFormat;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.renderer.GameRenderer;
import nl.requios.effortlessbuilding.create.foundation.utility.Color; import nl.requios.effortlessbuilding.create.foundation.utility.Color;
import nl.requios.effortlessbuilding.create.foundation.utility.Couple; import nl.requios.effortlessbuilding.create.foundation.utility.Couple;
import org.joml.Matrix4f;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.renderer.GameRenderer;
public class BoxElement extends RenderElement { public class BoxElement extends RenderElement {

View File

@@ -1,9 +1,10 @@
package nl.requios.effortlessbuilding.create.foundation.gui.element; package nl.requios.effortlessbuilding.create.foundation.gui.element;
import net.minecraft.client.gui.GuiGraphics;
import nl.requios.effortlessbuilding.create.foundation.gui.UIRenderHelper; import nl.requios.effortlessbuilding.create.foundation.gui.UIRenderHelper;
import nl.requios.effortlessbuilding.create.foundation.utility.Color; import nl.requios.effortlessbuilding.create.foundation.utility.Color;
import net.minecraft.client.gui.GuiGraphics;
public class DelegatedStencilElement extends StencilElement { public class DelegatedStencilElement extends StencilElement {
protected static final ElementRenderer EMPTY_RENDERER = (graphics, width, height, alpha) -> {}; protected static final ElementRenderer EMPTY_RENDERER = (graphics, width, height, alpha) -> {};

View File

@@ -1,13 +1,21 @@
package nl.requios.effortlessbuilding.create.foundation.gui.element; package nl.requios.effortlessbuilding.create.foundation.gui.element;
import javax.annotation.Nullable;
import com.jozufozu.flywheel.core.PartialModel;
import com.jozufozu.flywheel.core.model.ModelUtil;
import com.mojang.blaze3d.platform.GlStateManager;
import com.mojang.blaze3d.platform.GlStateManager.DestFactor; import com.mojang.blaze3d.platform.GlStateManager.DestFactor;
import com.mojang.blaze3d.platform.GlStateManager.SourceFactor; import com.mojang.blaze3d.platform.GlStateManager.SourceFactor;
import com.mojang.blaze3d.platform.Lighting; import com.mojang.blaze3d.platform.Lighting;
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.math.Axis; import com.mojang.math.Axis;
import dev.engine_room.flywheel.lib.model.baked.PartialModel; import nl.requios.effortlessbuilding.create.foundation.gui.ILightingSettings;
import net.createmod.ponder.render.VirtualRenderHelper; 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.Minecraft;
import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.renderer.LightTexture; import net.minecraft.client.renderer.LightTexture;
@@ -31,12 +39,7 @@ import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.Fluid; import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.phys.Vec3; import net.minecraft.world.phys.Vec3;
import net.minecraftforge.client.RenderTypeHelper; import net.minecraftforge.client.RenderTypeHelper;
import nl.requios.effortlessbuilding.create.foundation.gui.ILightingSettings; import net.minecraftforge.fluids.FluidStack;
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 javax.annotation.Nullable;
public class GuiGameElement { public class GuiGameElement {
@@ -184,19 +187,19 @@ public class GuiGameElement {
RenderType renderType = Sheets.translucentCullBlockSheet(); RenderType renderType = Sheets.translucentCullBlockSheet();
blockRenderer.getModelRenderer() blockRenderer.getModelRenderer()
.renderModel(ms.last(), buffer.getBuffer(renderType), blockState, blockModel, 1, 1, 1, .renderModel(ms.last(), buffer.getBuffer(renderType), blockState, blockModel, 1, 1, 1,
LightTexture.FULL_BRIGHT, OverlayTexture.NO_OVERLAY, VirtualRenderHelper.VIRTUAL_DATA, null); LightTexture.FULL_BRIGHT, OverlayTexture.NO_OVERLAY, ModelUtil.VIRTUAL_DATA, null);
} else { } else {
int color = Minecraft.getInstance() int color = Minecraft.getInstance()
.getBlockColors() .getBlockColors()
.getColor(blockState, null, null, 0); .getColor(blockState, null, null, 0);
Color rgb = new Color(color == -1 ? this.color : color); Color rgb = new Color(color == -1 ? this.color : color);
for (RenderType chunkType : blockModel.getRenderTypes(blockState, RandomSource.create(42L), VirtualRenderHelper.VIRTUAL_DATA)) { for (RenderType chunkType : blockModel.getRenderTypes(blockState, RandomSource.create(42L), ModelUtil.VIRTUAL_DATA)) {
RenderType renderType = RenderTypeHelper.getEntityRenderType(chunkType, true); RenderType renderType = RenderTypeHelper.getEntityRenderType(chunkType, true);
blockRenderer.getModelRenderer() blockRenderer.getModelRenderer()
.renderModel(ms.last(), buffer.getBuffer(renderType), blockState, blockModel, .renderModel(ms.last(), buffer.getBuffer(renderType), blockState, blockModel,
rgb.getRedAsFloat(), rgb.getGreenAsFloat(), rgb.getBlueAsFloat(), rgb.getRedAsFloat(), rgb.getGreenAsFloat(), rgb.getBlueAsFloat(),
LightTexture.FULL_BRIGHT, OverlayTexture.NO_OVERLAY, VirtualRenderHelper.VIRTUAL_DATA, chunkType); LightTexture.FULL_BRIGHT, OverlayTexture.NO_OVERLAY, ModelUtil.VIRTUAL_DATA, chunkType);
} }
} }
@@ -231,7 +234,7 @@ public class GuiGameElement {
// FluidRenderer.renderFluidBox(new FluidStack(blockState.getFluidState() // FluidRenderer.renderFluidBox(new FluidStack(blockState.getFluidState()
// .getType(), 1000), 0, 0, 0, 1, 1, 1, buffer, ms, LightTexture.FULL_BRIGHT, false); // .getType(), 1000), 0, 0, 0, 1, 1, 1, buffer, ms, LightTexture.FULL_BRIGHT, false);
// buffer.endBatch(); buffer.endBatch();
} }
} }
@@ -272,7 +275,7 @@ public class GuiGameElement {
RenderSystem.setShaderTexture(0, InventoryMenu.BLOCK_ATLAS); RenderSystem.setShaderTexture(0, InventoryMenu.BLOCK_ATLAS);
RenderSystem.enableBlend(); RenderSystem.enableBlend();
RenderSystem.enableCull(); RenderSystem.enableCull();
RenderSystem.blendFunc(SourceFactor.SRC_ALPHA, DestFactor.ONE_MINUS_SRC_ALPHA); RenderSystem.blendFunc(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA);
RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F); RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F);
matrixStack.pushPose(); matrixStack.pushPose();
matrixStack.translate(0, 0, 100.0F); matrixStack.translate(0, 0, 100.0F);

View File

@@ -1,10 +1,11 @@
package nl.requios.effortlessbuilding.create.foundation.gui.element; package nl.requios.effortlessbuilding.create.foundation.gui.element;
import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.PoseStack;
import nl.requios.effortlessbuilding.create.foundation.utility.Components;
import net.minecraft.client.gui.Font; import net.minecraft.client.gui.Font;
import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.network.chat.MutableComponent; import net.minecraft.network.chat.MutableComponent;
import nl.requios.effortlessbuilding.create.foundation.utility.Components;
public class TextStencilElement extends DelegatedStencilElement { public class TextStencilElement extends DelegatedStencilElement {

View File

@@ -1,6 +1,16 @@
package nl.requios.effortlessbuilding.create.foundation.gui.container; package nl.requios.effortlessbuilding.create.foundation.gui.menu;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import javax.annotation.ParametersAreNonnullByDefault;
import com.mojang.blaze3d.platform.InputConstants; import com.mojang.blaze3d.platform.InputConstants;
import nl.requios.effortlessbuilding.create.foundation.gui.AllGuiTextures;
import nl.requios.effortlessbuilding.create.foundation.gui.TickableGuiEventListener;
import nl.requios.effortlessbuilding.create.foundation.gui.widget.AbstractSimiWidget;
import net.minecraft.client.gui.GuiGraphics; 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.EditBox; import net.minecraft.client.gui.components.EditBox;
@@ -15,13 +25,6 @@ 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.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.api.distmarker.OnlyIn;
import nl.requios.effortlessbuilding.create.foundation.gui.TickableGuiEventListener;
import nl.requios.effortlessbuilding.create.foundation.gui.widget.AbstractSimiWidget;
import javax.annotation.ParametersAreNonnullByDefault;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
@OnlyIn(Dist.CLIENT) @OnlyIn(Dist.CLIENT)
@ParametersAreNonnullByDefault @ParametersAreNonnullByDefault
@@ -127,10 +130,10 @@ public abstract class AbstractSimiContainerScreen<T extends AbstractContainerMen
return leftPos - windowXOffset + (imageWidth - textureWidth) / 2; return leftPos - windowXOffset + (imageWidth - textureWidth) / 2;
} }
// public void renderPlayerInventory(GuiGraphics graphics, int x, int y) { public void renderPlayerInventory(GuiGraphics graphics, int x, int y) {
// AllGuiTextures.PLAYER_INVENTORY.render(graphics, x, y); // AllGuiTextures.PLAYER_INVENTORY.render(graphics, x, y);
// graphics.drawString(font, playerInventoryTitle, x + 8, y + 6, 0x404040, false); 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) {

View File

@@ -1,9 +1,10 @@
package nl.requios.effortlessbuilding.create.foundation.gui.container; package nl.requios.effortlessbuilding.create.foundation.gui.menu;
import nl.requios.effortlessbuilding.create.foundation.networking.SimplePacketBase;
import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.level.ServerPlayer;
import net.minecraftforge.network.NetworkEvent.Context; import net.minecraftforge.network.NetworkEvent.Context;
import nl.requios.effortlessbuilding.create.foundation.networking.SimplePacketBase;
public class ClearMenuPacket extends SimplePacketBase { public class ClearMenuPacket extends SimplePacketBase {

View File

@@ -1,4 +1,4 @@
package nl.requios.effortlessbuilding.create.foundation.gui.container; package nl.requios.effortlessbuilding.create.foundation.gui.menu;
import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.world.entity.player.Inventory; import net.minecraft.world.entity.player.Inventory;

View File

@@ -1,10 +1,11 @@
package nl.requios.effortlessbuilding.create.foundation.gui.container; package nl.requios.effortlessbuilding.create.foundation.gui.menu;
import nl.requios.effortlessbuilding.create.foundation.networking.SimplePacketBase;
import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.minecraftforge.network.NetworkEvent.Context; import net.minecraftforge.network.NetworkEvent.Context;
import nl.requios.effortlessbuilding.create.foundation.networking.SimplePacketBase;
public class GhostItemSubmitPacket extends SimplePacketBase { public class GhostItemSubmitPacket extends SimplePacketBase {

View File

@@ -0,0 +1,13 @@
package nl.requios.effortlessbuilding.create.foundation.gui.menu;
//import nl.requios.effortlessbuilding.create.AllPackets;
public interface IClearableMenu {
default void sendClearPacket() {
// AllPackets.getChannel().sendToServer(new ClearMenuPacket());
}
public void clearContents();
}

View File

@@ -1,4 +1,6 @@
package nl.requios.effortlessbuilding.create.foundation.gui.container; package nl.requios.effortlessbuilding.create.foundation.gui.menu;
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;
@@ -8,7 +10,6 @@ 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.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.api.distmarker.OnlyIn;
import nl.requios.effortlessbuilding.create.foundation.utility.IInteractionChecker;
public abstract class MenuBase<T> extends AbstractContainerMenu { public abstract class MenuBase<T> extends AbstractContainerMenu {

View File

@@ -1,18 +1,20 @@
package nl.requios.effortlessbuilding.create.foundation.gui.widget; package nl.requios.effortlessbuilding.create.foundation.gui.widget;
import java.util.LinkedList;
import java.util.List;
import java.util.function.BiConsumer;
import javax.annotation.Nonnull;
import nl.requios.effortlessbuilding.create.foundation.gui.TickableGuiEventListener;
import nl.requios.effortlessbuilding.create.foundation.utility.Components;
import net.minecraft.client.gui.GuiGraphics; 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.narration.NarrationElementOutput; import net.minecraft.client.gui.narration.NarrationElementOutput;
import net.minecraft.client.gui.screens.inventory.tooltip.ClientTooltipPositioner; import net.minecraft.client.gui.screens.inventory.tooltip.ClientTooltipPositioner;
import net.minecraft.client.gui.screens.inventory.tooltip.DefaultTooltipPositioner; import net.minecraft.client.gui.screens.inventory.tooltip.DefaultTooltipPositioner;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import nl.requios.effortlessbuilding.create.foundation.gui.TickableGuiEventListener;
import nl.requios.effortlessbuilding.create.foundation.utility.Components;
import javax.annotation.Nonnull;
import java.util.LinkedList;
import java.util.List;
import java.util.function.BiConsumer;
public abstract class AbstractSimiWidget extends AbstractWidget implements TickableGuiEventListener { public abstract class AbstractSimiWidget extends AbstractWidget implements TickableGuiEventListener {
@@ -38,7 +40,7 @@ public abstract class AbstractSimiWidget extends AbstractWidget implements Ticka
protected AbstractSimiWidget(int x, int y, int width, int height, Component message) { protected AbstractSimiWidget(int x, int y, int width, int height, Component message) {
super(x, y, width, height, message); super(x, y, width, height, message);
} }
@Override @Override
protected ClientTooltipPositioner createTooltipPositioner() { protected ClientTooltipPositioner createTooltipPositioner() {
return DefaultTooltipPositioner.INSTANCE; return DefaultTooltipPositioner.INSTANCE;
@@ -70,7 +72,7 @@ public abstract class AbstractSimiWidget extends AbstractWidget implements Ticka
@Override @Override
public void renderWidget(@Nonnull GuiGraphics graphics, int mouseX, int mouseY, float partialTicks) { public void renderWidget(@Nonnull GuiGraphics graphics, int mouseX, int mouseY, float partialTicks) {
beforeRender(graphics, mouseX, mouseY, partialTicks); beforeRender(graphics, mouseX, mouseY, partialTicks);
doRender(graphics, mouseX, mouseY, partialTicks); renderButton(graphics, mouseX, mouseY, partialTicks);
afterRender(graphics, mouseX, mouseY, partialTicks); afterRender(graphics, mouseX, mouseY, partialTicks);
wasHovered = isHoveredOrFocused(); wasHovered = isHoveredOrFocused();
} }
@@ -79,7 +81,7 @@ public abstract class AbstractSimiWidget extends AbstractWidget implements Ticka
graphics.pose().pushPose(); graphics.pose().pushPose();
} }
protected void doRender(@Nonnull GuiGraphics graphics, int mouseX, int mouseY, float partialTicks) { protected void renderButton(@Nonnull GuiGraphics graphics, int mouseX, int mouseY, float partialTicks) {
} }
protected void afterRender(@Nonnull GuiGraphics graphics, int mouseX, int mouseY, float partialTicks) { protected void afterRender(@Nonnull GuiGraphics graphics, int mouseX, int mouseY, float partialTicks) {

View File

@@ -1,7 +1,9 @@
package nl.requios.effortlessbuilding.create.foundation.gui.widget; package nl.requios.effortlessbuilding.create.foundation.gui.widget;
import net.minecraft.client.gui.GuiGraphics; import java.util.function.Function;
import nl.requios.effortlessbuilding.create.foundation.gui.Theme; 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.UIRenderHelper;
import nl.requios.effortlessbuilding.create.foundation.gui.element.BoxElement; import nl.requios.effortlessbuilding.create.foundation.gui.element.BoxElement;
import nl.requios.effortlessbuilding.create.foundation.gui.element.DelegatedStencilElement; import nl.requios.effortlessbuilding.create.foundation.gui.element.DelegatedStencilElement;
@@ -9,7 +11,7 @@ import nl.requios.effortlessbuilding.create.foundation.utility.Color;
import nl.requios.effortlessbuilding.create.foundation.utility.Couple; import nl.requios.effortlessbuilding.create.foundation.utility.Couple;
import nl.requios.effortlessbuilding.create.foundation.utility.animation.LerpedFloat; import nl.requios.effortlessbuilding.create.foundation.utility.animation.LerpedFloat;
import java.util.function.Function; import net.minecraft.client.gui.GuiGraphics;
public class BoxWidget extends ElementWidget { public class BoxWidget extends ElementWidget {
@@ -119,7 +121,7 @@ public class BoxWidget extends ElementWidget {
} }
@Override @Override
public void doRender(GuiGraphics graphics, int mouseX, int mouseY, float partialTicks) { public void renderButton(GuiGraphics graphics, int mouseX, int mouseY, float partialTicks) {
float fadeValue = fade.getValue(partialTicks); float fadeValue = fade.getValue(partialTicks);
if (fadeValue < .1f) if (fadeValue < .1f)
return; return;
@@ -131,7 +133,7 @@ public class BoxWidget extends ElementWidget {
.withBounds(width, height) .withBounds(width, height)
.render(graphics); .render(graphics);
super.doRender(graphics, mouseX, mouseY, partialTicks); super.renderButton(graphics, mouseX, mouseY, partialTicks);
wasHovered = isHovered; wasHovered = isHovered;
} }
@@ -146,7 +148,7 @@ public class BoxWidget extends ElementWidget {
return getX() - padX <= mX && getY() - padY <= mY && mX < getX() + padX + width && mY < getY() + padY + height; return getX() - padX <= mX && getY() - padY <= mY && mX < getX() + padX + width && mY < getY() + padY + height;
} }
@Override @Override
protected boolean clicked(double pMouseX, double pMouseY) { protected boolean clicked(double pMouseX, double pMouseY) {
if (!active || !visible) if (!active || !visible)
@@ -207,19 +209,19 @@ public class BoxWidget extends ElementWidget {
return customBorderBot != null ? customBorderBot : Theme.c(getIdleTheme(), false); return customBorderBot != null ? customBorderBot : Theme.c(getIdleTheme(), false);
} }
public Theme.Key getDisabledTheme() { public Key getDisabledTheme() {
return Theme.Key.BUTTON_DISABLE; return Theme.Key.BUTTON_DISABLE;
} }
public Theme.Key getIdleTheme() { public Key getIdleTheme() {
return Theme.Key.BUTTON_IDLE; return Theme.Key.BUTTON_IDLE;
} }
public Theme.Key getHoverTheme() { public Key getHoverTheme() {
return Theme.Key.BUTTON_HOVER; return Theme.Key.BUTTON_HOVER;
} }
public Theme.Key getClickTheme() { public Key getClickTheme() {
return Theme.Key.BUTTON_CLICK; return Theme.Key.BUTTON_CLICK;
} }

View File

@@ -1,13 +1,14 @@
package nl.requios.effortlessbuilding.create.foundation.gui.widget; package nl.requios.effortlessbuilding.create.foundation.gui.widget;
import java.util.function.Consumer;
import java.util.function.UnaryOperator;
import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.client.gui.GuiGraphics;
import nl.requios.effortlessbuilding.create.foundation.gui.element.RenderElement; import nl.requios.effortlessbuilding.create.foundation.gui.element.RenderElement;
import nl.requios.effortlessbuilding.create.foundation.gui.element.ScreenElement; import nl.requios.effortlessbuilding.create.foundation.gui.element.ScreenElement;
import nl.requios.effortlessbuilding.create.foundation.utility.animation.LerpedFloat; import nl.requios.effortlessbuilding.create.foundation.utility.animation.LerpedFloat;
import java.util.function.Consumer; import net.minecraft.client.gui.GuiGraphics;
import java.util.function.UnaryOperator;
public class ElementWidget extends AbstractSimiWidget { public class ElementWidget extends AbstractSimiWidget {
@@ -129,7 +130,7 @@ public class ElementWidget extends AbstractSimiWidget {
} }
@Override @Override
public void doRender(GuiGraphics graphics, int mouseX, int mouseY, float partialTicks) { public void renderButton(GuiGraphics graphics, int mouseX, int mouseY, float partialTicks) {
PoseStack ms = graphics.pose(); PoseStack ms = graphics.pose();
ms.pushPose(); ms.pushPose();
ms.translate(getX() + paddingX, getY() + paddingY, z); ms.translate(getX() + paddingX, getY() + paddingY, z);

View File

@@ -1,11 +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 net.minecraft.client.gui.GuiGraphics;
import net.minecraft.network.chat.Component;
import nl.requios.effortlessbuilding.create.foundation.gui.AllGuiTextures; import nl.requios.effortlessbuilding.create.foundation.gui.AllGuiTextures;
import nl.requios.effortlessbuilding.create.foundation.gui.element.ScreenElement; import nl.requios.effortlessbuilding.create.foundation.gui.element.ScreenElement;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.network.chat.Component;
public class IconButton extends AbstractSimiWidget { public class IconButton extends AbstractSimiWidget {
protected ScreenElement icon; protected ScreenElement icon;
@@ -13,14 +14,14 @@ 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 doRender(GuiGraphics graphics, int mouseX, int mouseY, float partialTicks) { public void renderButton(GuiGraphics graphics, int mouseX, int mouseY, float partialTicks) {
if (visible) { if (visible) {
isHovered = mouseX >= getX() && mouseY >= getY() && mouseX < getX() + width && mouseY < getY() + height; isHovered = mouseX >= getX() && mouseY >= getY() && mouseX < getX() + width && mouseY < getY() + height;

View File

@@ -1,9 +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 nl.requios.effortlessbuilding.create.foundation.gui.AllGuiTextures;
import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import nl.requios.effortlessbuilding.create.foundation.gui.AllGuiTextures;
public class Indicator extends AbstractSimiWidget { public class Indicator extends AbstractSimiWidget {

View File

@@ -1,14 +1,15 @@
package nl.requios.effortlessbuilding.create.foundation.gui.widget; package nl.requios.effortlessbuilding.create.foundation.gui.widget;
import javax.annotation.Nonnull;
import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.systems.RenderSystem;
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.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;
public class Label extends AbstractSimiWidget { public class Label extends AbstractSimiWidget {
@@ -70,7 +71,7 @@ public class Label extends AbstractSimiWidget {
} }
@Override @Override
protected void doRender(@Nonnull GuiGraphics graphics, int mouseX, int mouseY, float partialTicks) { protected void renderButton(@Nonnull GuiGraphics graphics, int mouseX, int mouseY, float partialTicks) {
if (text == null || text.getString().isEmpty()) if (text == null || text.getString().isEmpty())
return; return;

View File

@@ -1,15 +1,20 @@
package nl.requios.effortlessbuilding.create.foundation.gui.widget; package nl.requios.effortlessbuilding.create.foundation.gui.widget;
import net.minecraft.ChatFormatting;
import net.minecraft.network.chat.Component;
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;
import nl.requios.effortlessbuilding.create.AllKeys;
//import nl.requios.effortlessbuilding.create.AllSoundEvents;
//import nl.requios.effortlessbuilding.create.foundation.blockEntity.behaviour.scrollValue.ScrollValueBehaviour.StepContext;
import nl.requios.effortlessbuilding.create.foundation.utility.Components;
import nl.requios.effortlessbuilding.create.foundation.utility.Lang;
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.MutableComponent;
public class ScrollInput extends AbstractSimiWidget { public class ScrollInput extends AbstractSimiWidget {
protected Consumer<Integer> onScroll; protected Consumer<Integer> onScroll;
@@ -118,8 +123,6 @@ public class ScrollInput extends AbstractSimiWidget {
@Override @Override
public boolean mouseScrolled(double mouseX, double mouseY, double delta) { public boolean mouseScrolled(double mouseX, double mouseY, double delta) {
if (!this.visible || !this.isHovered) return false; //Added
if (inverted) if (inverted)
delta *= -1; delta *= -1;
@@ -149,8 +152,7 @@ public class ScrollInput extends AbstractSimiWidget {
onChanged(); onChanged();
} }
// return priorState != state; return priorState != state;
return true; //Changed
} }
protected void clampState() { protected void clampState() {

View File

@@ -1,13 +1,14 @@
package nl.requios.effortlessbuilding.create.foundation.gui.widget; package nl.requios.effortlessbuilding.create.foundation.gui.widget;
import java.util.ArrayList;
import java.util.List;
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.List;
public class SelectionScrollInput extends ScrollInput { public class SelectionScrollInput extends ScrollInput {

View File

@@ -1,182 +1,253 @@
package nl.requios.effortlessbuilding.create.foundation.item; package nl.requios.effortlessbuilding.create.foundation.item;
import net.minecraft.ChatFormatting; import static net.minecraft.ChatFormatting.DARK_GRAY;
import net.minecraft.client.gui.screens.Screen; import static net.minecraft.ChatFormatting.GRAY;
import net.minecraft.network.chat.Component; import static net.minecraft.ChatFormatting.WHITE;
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.Arrays; import java.util.Arrays;
import java.util.IdentityHashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.function.Supplier;
import static net.minecraft.ChatFormatting.*; import org.apache.commons.lang3.tuple.Pair;
import static nl.requios.effortlessbuilding.create.foundation.item.TooltipHelper.cutStringTextComponent; import org.jetbrains.annotations.Nullable;
import static nl.requios.effortlessbuilding.create.foundation.item.TooltipHelper.cutTextComponent;
public class ItemDescription { import com.google.common.collect.ImmutableList;
import nl.requios.effortlessbuilding.create.foundation.item.TooltipHelper.Palette;
import nl.requios.effortlessbuilding.create.foundation.utility.Components;
import nl.requios.effortlessbuilding.create.foundation.utility.Lang;
public static final ItemDescription MISSING = new ItemDescription(null); import net.minecraft.client.Minecraft;
public static Component trim = Components.literal(" ").withStyle(WHITE, STRIKETHROUGH); import net.minecraft.client.gui.screens.Screen;
import net.minecraft.client.resources.language.I18n;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.MutableComponent;
import net.minecraft.world.item.Item;
import net.minecraft.world.level.ItemLike;
import net.minecraftforge.event.entity.player.ItemTooltipEvent;
public enum Palette { public record ItemDescription(ImmutableList<Component> lines, ImmutableList<Component> linesOnShift, ImmutableList<Component> linesOnCtrl) {
private static final Map<Item, Supplier<String>> CUSTOM_TOOLTIP_KEYS = new IdentityHashMap<>();
Blue(BLUE, AQUA), @Nullable
Green(DARK_GREEN, GREEN), public static ItemDescription create(Item item, Palette palette) {
Yellow(GOLD, YELLOW), return create(getTooltipTranslationKey(item), palette);
Red(DARK_RED, RED), }
Purple(DARK_PURPLE, LIGHT_PURPLE),
Gray(DARK_GRAY, GRAY),
; @Nullable
public static ItemDescription create(String translationKey, Palette palette) {
private Palette(ChatFormatting primary, ChatFormatting highlight) { if (!canFillBuilder(translationKey)) {
color = primary; return null;
hColor = highlight;
} }
public ChatFormatting color; Builder builder = new Builder(palette);
public ChatFormatting hColor; fillBuilder(builder, translationKey);
return builder.build();
} }
private List<Component> lines; public static boolean canFillBuilder(String translationKey) {
private List<Component> linesOnShift; return I18n.exists(translationKey);
private List<Component> linesOnCtrl;
private Palette palette;
public ItemDescription(Palette palette) {
this.palette = palette;
lines = new ArrayList<>();
linesOnShift = new ArrayList<>();
linesOnCtrl = new ArrayList<>();
} }
public ItemDescription withSummary(Component summary) { public static void fillBuilder(Builder builder, String translationKey) {
addStrings(linesOnShift, cutTextComponent(summary, palette.color, palette.hColor)); // Summary
return this; String summaryKey = translationKey + ".summary";
} if (I18n.exists(summaryKey)) {
builder.addSummary(I18n.get(summaryKey));
public static String makeProgressBar(int length, int filledLength) {
String bar = " ";
int emptySpaces = length - filledLength;
for (int i = 0; i < filledLength; i++)
bar += "\u2588";
for (int i = 0; i < emptySpaces; i++)
bar += "\u2592";
return bar + " ";
}
public ItemDescription withBehaviour(String condition, String behaviour) {
add(linesOnShift, Components.literal(condition).withStyle(GRAY));
addStrings(linesOnShift, cutStringTextComponent(behaviour, palette.color, palette.hColor, 1));
return this;
}
public ItemDescription withControl(String condition, String action) {
add(linesOnCtrl, Components.literal(condition).withStyle(GRAY));
addStrings(linesOnCtrl, cutStringTextComponent(action, palette.color, palette.hColor, 1));
return this;
}
public ItemDescription createTabs() {
boolean hasDescription = !linesOnShift.isEmpty();
boolean hasControls = !linesOnCtrl.isEmpty();
if (hasDescription || hasControls) {
String[] holdDesc = Lang.translateDirect("tooltip.holdForDescription", "$")
.getString()
.split("\\$");
String[] holdCtrl = Lang.translateDirect("tooltip.holdForControls", "$")
.getString()
.split("\\$");
MutableComponent keyShift = Lang.translateDirect("tooltip.keyShift");
MutableComponent keyCtrl = Lang.translateDirect("tooltip.keyCtrl");
for (List<Component> list : Arrays.asList(lines, linesOnShift, linesOnCtrl)) {
boolean shift = list == linesOnShift;
boolean ctrl = list == linesOnCtrl;
if (holdDesc.length != 2 || holdCtrl.length != 2) {
list.add(0, Components.literal("Invalid lang formatting!"));
continue;
}
if (hasControls) {
MutableComponent tabBuilder = Components.empty();
tabBuilder.append(Components.literal(holdCtrl[0]).withStyle(DARK_GRAY));
tabBuilder.append(keyCtrl.plainCopy()
.withStyle(ctrl ? WHITE : GRAY));
tabBuilder.append(Components.literal(holdCtrl[1]).withStyle(DARK_GRAY));
list.add(0, tabBuilder);
}
if (hasDescription) {
MutableComponent tabBuilder = Components.empty();
tabBuilder.append(Components.literal(holdDesc[0]).withStyle(DARK_GRAY));
tabBuilder.append(keyShift.plainCopy()
.withStyle(shift ? WHITE : GRAY));
tabBuilder.append(Components.literal(holdDesc[1]).withStyle(DARK_GRAY));
list.add(0, tabBuilder);
}
if (shift || ctrl)
list.add(hasDescription && hasControls ? 2 : 1, Components.immutableEmpty());
}
} }
if (!hasDescription) // Behaviours
linesOnShift = lines; for (int i = 1; i < 100; i++) {
if (!hasControls) String conditionKey = translationKey + ".condition" + i;
linesOnCtrl = lines; String behaviourKey = translationKey + ".behaviour" + i;
if (!I18n.exists(conditionKey))
break;
builder.addBehaviour(I18n.get(conditionKey), I18n.get(behaviourKey));
}
return this; // Actions
for (int i = 1; i < 100; i++) {
String controlKey = translationKey + ".control" + i;
String actionKey = translationKey + ".action" + i;
if (!I18n.exists(controlKey))
break;
builder.addAction(I18n.get(controlKey), I18n.get(actionKey));
}
} }
public static String hightlight(String s, Palette palette) { public static void useKey(Item item, Supplier<String> supplier) {
return palette.hColor + s + palette.color; CUSTOM_TOOLTIP_KEYS.put(item, supplier);
} }
public static void addStrings(List<Component> infoList, List<Component> textLines) { public static void useKey(ItemLike item, String string) {
textLines.forEach(s -> add(infoList, s)); useKey(item.asItem(), () -> string);
} }
public static void add(List<Component> infoList, List<Component> textLines) { public static void referKey(ItemLike item, Supplier<? extends ItemLike> otherItem) {
infoList.addAll(textLines); useKey(item.asItem(), () -> otherItem.get()
.asItem()
.getDescriptionId());
} }
public static void add(List<Component> infoList, Component line) { public static String getTooltipTranslationKey(Item item) {
infoList.add(line); if (CUSTOM_TOOLTIP_KEYS.containsKey(item)) {
return CUSTOM_TOOLTIP_KEYS.get(item).get() + ".tooltip";
}
return item.getDescriptionId() + ".tooltip";
} }
public Palette getPalette() { public ImmutableList<Component> getCurrentLines() {
return palette;
}
public List<Component> addInformation(List<Component> tooltip) {
if (Screen.hasShiftDown()) { if (Screen.hasShiftDown()) {
tooltip.addAll(linesOnShift); return linesOnShift;
return tooltip; } else if (Screen.hasControlDown()) {
return linesOnCtrl;
} else {
return lines;
}
}
public static class Builder {
protected final Palette palette;
protected final List<String> summary = new ArrayList<>();
protected final List<Pair<String, String>> behaviours = new ArrayList<>();
protected final List<Pair<String, String>> actions = new ArrayList<>();
public Builder(Palette palette) {
this.palette = palette;
} }
if (Screen.hasControlDown()) { public Builder addSummary(String summaryLine) {
tooltip.addAll(linesOnCtrl); summary.add(summaryLine);
return tooltip; return this;
} }
tooltip.addAll(lines); public Builder addBehaviour(String condition, String behaviour) {
return tooltip; behaviours.add(Pair.of(condition, behaviour));
return this;
}
public Builder addAction(String condition, String action) {
actions.add(Pair.of(condition, action));
return this;
}
public ItemDescription build() {
List<Component> lines = new ArrayList<>();
List<Component> linesOnShift = new ArrayList<>();
List<Component> linesOnCtrl = new ArrayList<>();
for (String summaryLine : summary) {
linesOnShift.addAll(TooltipHelper.cutStringTextComponent(summaryLine, palette));
}
if (!behaviours.isEmpty()) {
linesOnShift.add(Components.immutableEmpty());
}
for (Pair<String, String> behaviourPair : behaviours) {
String condition = behaviourPair.getLeft();
String behaviour = behaviourPair.getRight();
linesOnShift.add(Components.literal(condition).withStyle(GRAY));
linesOnShift.addAll(TooltipHelper.cutStringTextComponent(behaviour, palette.primary(), palette.highlight(), 1));
}
for (Pair<String, String> actionPair : actions) {
String condition = actionPair.getLeft();
String action = actionPair.getRight();
linesOnCtrl.add(Components.literal(condition).withStyle(GRAY));
linesOnCtrl.addAll(TooltipHelper.cutStringTextComponent(action, palette.primary(), palette.highlight(), 1));
}
boolean hasDescription = !linesOnShift.isEmpty();
boolean hasControls = !linesOnCtrl.isEmpty();
if (hasDescription || hasControls) {
String[] holdDesc = Lang.translateDirect("tooltip.holdForDescription", "$")
.getString()
.split("\\$");
String[] holdCtrl = Lang.translateDirect("tooltip.holdForControls", "$")
.getString()
.split("\\$");
MutableComponent keyShift = Lang.translateDirect("tooltip.keyShift");
MutableComponent keyCtrl = Lang.translateDirect("tooltip.keyCtrl");
for (List<Component> list : Arrays.asList(lines, linesOnShift, linesOnCtrl)) {
boolean shift = list == linesOnShift;
boolean ctrl = list == linesOnCtrl;
if (holdDesc.length != 2 || holdCtrl.length != 2) {
list.add(0, Components.literal("Invalid lang formatting!"));
continue;
}
if (hasControls) {
MutableComponent tabBuilder = Components.empty();
tabBuilder.append(Components.literal(holdCtrl[0]).withStyle(DARK_GRAY));
tabBuilder.append(keyCtrl.plainCopy()
.withStyle(ctrl ? WHITE : GRAY));
tabBuilder.append(Components.literal(holdCtrl[1]).withStyle(DARK_GRAY));
list.add(0, tabBuilder);
}
if (hasDescription) {
MutableComponent tabBuilder = Components.empty();
tabBuilder.append(Components.literal(holdDesc[0]).withStyle(DARK_GRAY));
tabBuilder.append(keyShift.plainCopy()
.withStyle(shift ? WHITE : GRAY));
tabBuilder.append(Components.literal(holdDesc[1]).withStyle(DARK_GRAY));
list.add(0, tabBuilder);
}
if (shift || ctrl)
list.add(hasDescription && hasControls ? 2 : 1, Components.immutableEmpty());
}
}
if (!hasDescription) {
linesOnCtrl.clear();
linesOnShift.addAll(lines);
}
if (!hasControls) {
linesOnCtrl.clear();
linesOnCtrl.addAll(lines);
}
return new ItemDescription(ImmutableList.copyOf(lines), ImmutableList.copyOf(linesOnShift), ImmutableList.copyOf(linesOnCtrl));
}
} }
public List<Component> getLines() { public static class Modifier implements TooltipModifier {
return lines; protected final Item item;
} protected final Palette palette;
protected String cachedLanguage;
protected ItemDescription description;
public List<Component> getLinesOnCtrl() { public Modifier(Item item, Palette palette) {
return linesOnCtrl; this.item = item;
} this.palette = palette;
}
public List<Component> getLinesOnShift() { @Override
return linesOnShift; public void modify(ItemTooltipEvent context) {
} if (checkLocale()) {
description = create(item, palette);
}
if (description == null) {
return;
}
context.getToolTip().addAll(1, description.getCurrentLines());
}
protected boolean checkLocale() {
String currentLanguage = Minecraft.getInstance()
.getLanguageManager()
.getSelected();
if (!currentLanguage.equals(cachedLanguage)) {
cachedLanguage = currentLanguage;
return true;
}
return false;
}
}
} }

View File

@@ -1,6 +1,16 @@
package nl.requios.effortlessbuilding.create.foundation.item; package nl.requios.effortlessbuilding.create.foundation.item;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;
import java.util.function.Predicate;
import javax.annotation.Nullable;
import org.apache.commons.lang3.mutable.MutableInt;
import nl.requios.effortlessbuilding.create.foundation.utility.Pair; import nl.requios.effortlessbuilding.create.foundation.utility.Pair;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.core.NonNullList; import net.minecraft.core.NonNullList;
import net.minecraft.util.Mth; import net.minecraft.util.Mth;
@@ -10,16 +20,17 @@ 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.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.ItemHandlerHelper; import net.minecraftforge.items.ItemHandlerHelper;
import org.apache.commons.lang3.mutable.MutableInt;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;
import java.util.function.Predicate;
public class ItemHelper { public class ItemHelper {
public static boolean sameItem(ItemStack stack, ItemStack otherStack) {
return !otherStack.isEmpty() && stack.is(otherStack.getItem());
}
public static Predicate<ItemStack> sameItemPredicate(ItemStack stack) {
return s -> sameItem(stack, s);
}
public static void dropContents(Level world, BlockPos pos, IItemHandler inv) { public static void dropContents(Level world, BlockPos pos, IItemHandler inv) {
for (int slot = 0; slot < inv.getSlots(); slot++) for (int slot = 0; slot < inv.getSlots(); slot++)
Containers.dropItemStack(world, pos.getX(), pos.getY(), pos.getZ(), inv.getStackInSlot(slot)); Containers.dropItemStack(world, pos.getX(), pos.getY(), pos.getZ(), inv.getStackInSlot(slot));

View File

@@ -1,37 +1,28 @@
package nl.requios.effortlessbuilding.create.foundation.item; package nl.requios.effortlessbuilding.create.foundation.item;
import com.google.common.base.Strings;
import net.minecraft.ChatFormatting;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.Font;
import net.minecraft.client.resources.language.I18n;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.MutableComponent;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
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.Couple;
import nl.requios.effortlessbuilding.create.foundation.utility.FontHelper;
import nl.requios.effortlessbuilding.create.foundation.utility.Lang;
import java.text.BreakIterator; import java.text.BreakIterator;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.function.Supplier; import com.google.common.base.Strings;
//import nl.requios.effortlessbuilding.create.content.equipment.goggles.IHaveGoggleInformation;
import nl.requios.effortlessbuilding.create.foundation.utility.Components;
import nl.requios.effortlessbuilding.create.foundation.utility.Couple;
import nl.requios.effortlessbuilding.create.foundation.utility.Lang;
import net.minecraft.ChatFormatting;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.Font;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.MutableComponent;
import net.minecraft.network.chat.Style;
public class TooltipHelper { public class TooltipHelper {
public static final int maxWidthPerLine = 200; public static final int MAX_WIDTH_PER_LINE = 200;
public static final Map<String, ItemDescription> cachedTooltips = new HashMap<>();
private static boolean gogglesMode;
private static final Map<Item, Supplier<String>> tooltipReferrals = new HashMap<>();
public static MutableComponent holdShift(Palette color, boolean highlighted) { public static MutableComponent holdShift(Palette palette, boolean highlighted) {
return Lang.translateDirect("tooltip.holdForDescription", Lang.translateDirect("tooltip.keyShift") return Lang.translateDirect("tooltip.holdForDescription", Lang.translateDirect("tooltip.keyShift")
.withStyle(ChatFormatting.GRAY)) .withStyle(ChatFormatting.GRAY))
.withStyle(ChatFormatting.DARK_GRAY); .withStyle(ChatFormatting.DARK_GRAY);
@@ -43,87 +34,64 @@ public class TooltipHelper {
.append(Lang.translateDirect(hintKey + ".title")) .append(Lang.translateDirect(hintKey + ".title"))
.withStyle(ChatFormatting.GOLD)); .withStyle(ChatFormatting.GOLD));
Component hint = Lang.translateDirect(hintKey); Component hint = Lang.translateDirect(hintKey);
List<Component> cutComponent = TooltipHelper.cutTextComponent(hint, ChatFormatting.GRAY, ChatFormatting.WHITE); List<Component> cutComponent = cutTextComponent(hint, Palette.GRAY_AND_WHITE);
for (Component component : cutComponent) for (Component component : cutComponent)
tooltip.add(spacing.plainCopy() tooltip.add(spacing.plainCopy()
.append(component)); .append(component));
} }
public static void referTo(ItemLike item, Supplier<? extends ItemLike> itemWithTooltip) { public static String makeProgressBar(int length, int filledLength) {
tooltipReferrals.put(item.asItem(), () -> itemWithTooltip.get() String bar = " ";
.asItem() int emptySpaces = length - filledLength;
.getDescriptionId()); for (int i = 0; i < filledLength; i++)
bar += "\u2588";
for (int i = 0; i < emptySpaces; i++)
bar += "\u2592";
return bar + " ";
} }
public static void referTo(ItemLike item, String string) { public static Style styleFromColor(ChatFormatting color) {
tooltipReferrals.put(item.asItem(), () -> string); return Style.EMPTY.applyFormat(color);
}
public static Style styleFromColor(int hex) {
return Style.EMPTY.withColor(hex);
} }
@Deprecated public static List<Component> cutStringTextComponent(String s, Palette palette) {
public static List<String> cutString(Component s, ChatFormatting defaultColor, ChatFormatting highlightColor) { return cutTextComponent(Components.literal(s), palette);
return cutString(s.getString(), defaultColor, highlightColor, 0);
} }
@Deprecated public static List<Component> cutTextComponent(Component c, Palette palette) {
public static List<String> cutString(String s, ChatFormatting defaultColor, ChatFormatting highlightColor, return cutTextComponent(c, palette.primary(), palette.highlight());
int indent) {
// Apply markup
String markedUp = s.replaceAll("_([^_]+)_", highlightColor + "$1" + defaultColor);
// Split words
List<String> words = new LinkedList<>();
BreakIterator iterator = BreakIterator.getLineInstance(Minecraft.getInstance().getLocale());
iterator.setText(markedUp);
int start = iterator.first();
for (int end = iterator.next(); end != BreakIterator.DONE; start = end, end = iterator.next()) {
String word = markedUp.substring(start, end);
words.add(word);
}
Font font = Minecraft.getInstance().font;
List<String> lines = FontHelper.cutString(font, markedUp, maxWidthPerLine);
// Format
String lineStart = Strings.repeat(" ", indent);
List<String> formattedLines = new ArrayList<>(lines.size());
String format = defaultColor.toString();
for (String line : lines) {
String formattedLine = format + lineStart + line;
formattedLines.add(formattedLine);
// format = TextFormatting.getFormatString(formattedLine);
}
return formattedLines;
} }
public static List<Component> cutStringTextComponent(String c, ChatFormatting defaultColor, public static List<Component> cutStringTextComponent(String s, Style primaryStyle,
ChatFormatting highlightColor) { Style highlightStyle) {
return cutTextComponent(Components.literal(c), defaultColor, highlightColor, 0); return cutTextComponent(Components.literal(s), primaryStyle, highlightStyle);
} }
public static List<Component> cutTextComponent(Component c, ChatFormatting defaultColor, public static List<Component> cutTextComponent(Component c, Style primaryStyle,
ChatFormatting highlightColor) { Style highlightStyle) {
return cutTextComponent(c, defaultColor, highlightColor, 0); return cutTextComponent(c, primaryStyle, highlightStyle, 0);
} }
public static List<Component> cutStringTextComponent(String c, ChatFormatting defaultColor, public static List<Component> cutStringTextComponent(String c, Style primaryStyle,
ChatFormatting highlightColor, int indent) { Style highlightStyle, int indent) {
return cutTextComponent(Components.literal(c), defaultColor, highlightColor, indent); return cutTextComponent(Components.literal(c), primaryStyle, highlightStyle, indent);
} }
public static List<Component> cutTextComponent(Component c, ChatFormatting defaultColor, public static List<Component> cutTextComponent(Component c, Style primaryStyle,
ChatFormatting highlightColor, int indent) { Style highlightStyle, int indent) {
String s = c.getString(); String s = c.getString();
// Apply markup
String markedUp = s;// .replaceAll("_([^_]+)_", highlightColor + "$1" + defaultColor);
// Split words // Split words
List<String> words = new LinkedList<>(); List<String> words = new LinkedList<>();
BreakIterator iterator = BreakIterator.getLineInstance(Minecraft.getInstance().getLocale()); BreakIterator iterator = BreakIterator.getLineInstance(Minecraft.getInstance().getLocale());
iterator.setText(markedUp); iterator.setText(s);
int start = iterator.first(); int start = iterator.first();
for (int end = iterator.next(); end != BreakIterator.DONE; start = end, end = iterator.next()) { for (int end = iterator.next(); end != BreakIterator.DONE; start = end, end = iterator.next()) {
String word = markedUp.substring(start, end); String word = s.substring(start, end);
words.add(word); words.add(word);
} }
@@ -134,7 +102,7 @@ public class TooltipHelper {
int width = 0; int width = 0;
for (String word : words) { for (String word : words) {
int newWidth = font.width(word.replaceAll("_", "")); int newWidth = font.width(word.replaceAll("_", ""));
if (width + newWidth > maxWidthPerLine) { if (width + newWidth > MAX_WIDTH_PER_LINE) {
if (width > 0) { if (width > 0) {
String line = currentLine.toString(); String line = currentLine.toString();
lines.add(line); lines.add(line);
@@ -154,16 +122,16 @@ public class TooltipHelper {
// Format // Format
MutableComponent lineStart = Components.literal(Strings.repeat(" ", indent)); MutableComponent lineStart = Components.literal(Strings.repeat(" ", indent));
lineStart.withStyle(defaultColor); lineStart.withStyle(primaryStyle);
List<Component> formattedLines = new ArrayList<>(lines.size()); List<Component> formattedLines = new ArrayList<>(lines.size());
Couple<ChatFormatting> f = Couple.create(highlightColor, defaultColor); Couple<Style> styles = Couple.create(highlightStyle, primaryStyle);
boolean currentlyHighlighted = false; boolean currentlyHighlighted = false;
for (String string : lines) { for (String string : lines) {
MutableComponent currentComponent = lineStart.plainCopy(); MutableComponent currentComponent = lineStart.plainCopy();
String[] split = string.split("_"); String[] split = string.split("_");
for (String part : split) { for (String part : split) {
currentComponent.append(Components.literal(part).withStyle(f.get(currentlyHighlighted))); currentComponent.append(Components.literal(part).withStyle(styles.get(currentlyHighlighted)));
currentlyHighlighted = !currentlyHighlighted; currentlyHighlighted = !currentlyHighlighted;
} }
@@ -174,110 +142,25 @@ public class TooltipHelper {
return formattedLines; return formattedLines;
} }
// public static List<ITextComponent> cutTextComponentOld(ITextComponent c, TextFormatting defaultColor, public record Palette(Style primary, Style highlight) {
// TextFormatting highlightColor, int indent) { public static final Palette STANDARD_CREATE = new Palette(styleFromColor(0xC9974C), styleFromColor(0xF1DD79));
// IFormattableTextComponent lineStart = StringTextComponent.EMPTY.copy();
// for (int i = 0; i < indent; i++)
// lineStart.append(" ");
// lineStart.formatted(defaultColor);
//
// List<ITextComponent> lines = new ArrayList<>();
// String rawText = getUnformattedDeepText(c);
// String[] words = rawText.split(" ");
// String word;
// IFormattableTextComponent currentLine = lineStart.copy();
//
// boolean firstWord = true;
// boolean lastWord;
//
// // Apply hard wrap
// for (int i = 0; i < words.length; i++) {
// word = words[i];
// lastWord = i == words.length - 1;
//
// if (!lastWord && !firstWord && getComponentLength(currentLine) + word.length() > maxCharsPerLine) {
// lines.add(currentLine);
// currentLine = lineStart.copy();
// firstWord = true;
// }
//
// currentLine.append(new StringTextComponent((firstWord ? "" : " ") + word.replace("_", ""))
// .formatted(word.matches("_([^_]+)_") ? highlightColor : defaultColor));
// firstWord = false;
// }
//
// if (!firstWord) {
// lines.add(currentLine);
// }
//
// return lines;
// }
private static boolean findTooltip(ItemStack stack) { public static final Palette BLUE = ofColors(ChatFormatting.BLUE, ChatFormatting.AQUA);
String key = getTooltipTranslationKey(stack); public static final Palette GREEN = ofColors(ChatFormatting.DARK_GREEN, ChatFormatting.GREEN);
if (I18n.exists(key)) { public static final Palette YELLOW = ofColors(ChatFormatting.GOLD, ChatFormatting.YELLOW);
cachedTooltips.put(key, buildToolTip(key, stack)); public static final Palette RED = ofColors(ChatFormatting.DARK_RED, ChatFormatting.RED);
return true; public static final Palette PURPLE = ofColors(ChatFormatting.DARK_PURPLE, ChatFormatting.LIGHT_PURPLE);
public static final Palette GRAY = ofColors(ChatFormatting.DARK_GRAY, ChatFormatting.GRAY);
public static final Palette ALL_GRAY = ofColors(ChatFormatting.GRAY, ChatFormatting.GRAY);
public static final Palette GRAY_AND_BLUE = ofColors(ChatFormatting.GRAY, ChatFormatting.BLUE);
public static final Palette GRAY_AND_WHITE = ofColors(ChatFormatting.GRAY, ChatFormatting.WHITE);
public static final Palette GRAY_AND_GOLD = ofColors(ChatFormatting.GRAY, ChatFormatting.GOLD);
public static final Palette GRAY_AND_RED = ofColors(ChatFormatting.GRAY, ChatFormatting.RED);
public static Palette ofColors(ChatFormatting primary, ChatFormatting highlight) {
return new Palette(styleFromColor(primary), styleFromColor(highlight));
} }
cachedTooltips.put(key, ItemDescription.MISSING);
return false;
} }
private static ItemDescription buildToolTip(String translationKey, ItemStack stack) {
ItemDescription tooltip = new ItemDescription(Palette.Blue);
String summaryKey = translationKey + ".summary";
// Summary
if (I18n.exists(summaryKey))
tooltip = tooltip.withSummary(Components.literal(I18n.get(summaryKey)));
// Requirements
// if (stack.getItem() instanceof BlockItem) {
// BlockItem item = (BlockItem) stack.getItem();
// if (item.getBlock() instanceof IRotate || item.getBlock() instanceof EngineBlock) {
// tooltip = tooltip.withKineticStats(item.getBlock());
// }
// }
// Behaviours
for (int i = 1; i < 100; i++) {
String conditionKey = translationKey + ".condition" + i;
String behaviourKey = translationKey + ".behaviour" + i;
if (!I18n.exists(conditionKey))
break;
if (i == 1)
tooltip.getLinesOnShift()
.add(Components.immutableEmpty());
tooltip.withBehaviour(I18n.get(conditionKey), I18n.get(behaviourKey));
}
// Controls
for (int i = 1; i < 100; i++) {
String controlKey = translationKey + ".control" + i;
String actionKey = translationKey + ".action" + i;
if (!I18n.exists(controlKey))
break;
tooltip.withControl(I18n.get(controlKey), I18n.get(actionKey));
}
return tooltip.createTabs();
}
public static String getTooltipTranslationKey(ItemStack stack) {
Item item = stack.getItem();
if (tooltipReferrals.containsKey(item))
return tooltipReferrals.get(item)
.get() + ".tooltip";
return item.getDescriptionId(stack) + ".tooltip";
}
// private static int getComponentLength(ITextComponent component) {
// AtomicInteger l = new AtomicInteger();
// TextProcessing.visitFormatted(component, Style.EMPTY, (s, style, charConsumer) -> {
// l.getAndIncrement();
// return true;
// });
// return l.get();
// }
} }

View File

@@ -0,0 +1,43 @@
package nl.requios.effortlessbuilding.create.foundation.item;
import org.jetbrains.annotations.Nullable;
import nl.requios.effortlessbuilding.create.foundation.utility.AttachedRegistry;
import net.minecraft.world.item.Item;
import net.minecraftforge.event.entity.player.ItemTooltipEvent;
import net.minecraftforge.registries.ForgeRegistries;
public interface TooltipModifier {
AttachedRegistry<Item, TooltipModifier> REGISTRY = new AttachedRegistry<>(ForgeRegistries.ITEMS);
TooltipModifier EMPTY = new TooltipModifier() {
@Override
public void modify(ItemTooltipEvent context) {
}
@Override
public TooltipModifier andThen(TooltipModifier after) {
return after;
}
};
void modify(ItemTooltipEvent context);
default TooltipModifier andThen(TooltipModifier after) {
if (after == EMPTY) {
return this;
}
return tooltip -> {
modify(tooltip);
after.modify(tooltip);
};
}
static TooltipModifier mapNull(@Nullable TooltipModifier modifier) {
if (modifier == null) {
return EMPTY;
}
return modifier;
}
}

View File

@@ -1,6 +1,7 @@
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.resources.model.BakedModel; import net.minecraft.client.resources.model.BakedModel;
import net.minecraft.world.item.ItemDisplayContext; import net.minecraft.world.item.ItemDisplayContext;
import net.minecraftforge.client.model.BakedModelWrapper; import net.minecraftforge.client.model.BakedModelWrapper;
@@ -18,7 +19,7 @@ public class CustomRenderedItemModel extends BakedModelWrapper<BakedModel> {
@Override @Override
public BakedModel applyTransform(ItemDisplayContext cameraItemDisplayContext, PoseStack mat, public BakedModel applyTransform(ItemDisplayContext cameraItemDisplayContext, PoseStack mat,
boolean leftHand) { boolean leftHand) {
// Super call returns originalModel, but we want to return this, else BEWLR // Super call returns originalModel, but we want to return this, else BEWLR
// won't be used. // won't be used.
super.applyTransform(cameraItemDisplayContext, mat, leftHand); super.applyTransform(cameraItemDisplayContext, mat, leftHand);

View File

@@ -0,0 +1,33 @@
package nl.requios.effortlessbuilding.create.foundation.item.render;
import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.BlockEntityWithoutLevelRenderer;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.world.item.ItemDisplayContext;
import net.minecraft.world.item.ItemStack;
public abstract class CustomRenderedItemModelRenderer extends BlockEntityWithoutLevelRenderer {
public CustomRenderedItemModelRenderer() {
super(null, null);
}
@Override
public void renderByItem(ItemStack stack, ItemDisplayContext transformType, PoseStack ms, MultiBufferSource buffer, int light, int overlay) {
CustomRenderedItemModel mainModel = (CustomRenderedItemModel) Minecraft.getInstance()
.getItemRenderer()
.getModel(stack, null, null, 0);
PartialItemModelRenderer renderer = PartialItemModelRenderer.of(stack, transformType, ms, buffer, overlay);
ms.pushPose();
ms.translate(0.5F, 0.5F, 0.5F);
render(stack, mainModel, renderer, transformType, ms, buffer, light, overlay);
ms.popPose();
}
protected abstract void render(ItemStack stack, CustomRenderedItemModel model, PartialItemModelRenderer renderer, ItemDisplayContext transformType,
PoseStack ms, MultiBufferSource buffer, int light, int overlay);
}

View File

@@ -2,6 +2,9 @@ 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 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;
@@ -13,8 +16,6 @@ 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.minecraftforge.client.extensions.common.IClientItemExtensions;
import net.minecraftforge.client.model.data.ModelData; import net.minecraftforge.client.model.data.ModelData;
import nl.requios.effortlessbuilding.create.foundation.render.RenderTypes;
import nl.requios.effortlessbuilding.create.foundation.utility.Iterate;
public class PartialItemModelRenderer { public class PartialItemModelRenderer {
@@ -47,13 +48,13 @@ public class PartialItemModelRenderer {
render(model, RenderTypes.getItemPartialSolid(), light); render(model, RenderTypes.getItemPartialSolid(), light);
} }
// public void renderSolidGlowing(BakedModel model, int light) { public void renderSolidGlowing(BakedModel model, int light) {
// render(model, RenderTypes.getGlowingSolid(), light); render(model, RenderTypes.getGlowingSolid(), light);
// } }
//
// public void renderGlowing(BakedModel model, int light) { public void renderGlowing(BakedModel model, int light) {
// render(model, RenderTypes.getGlowingTranslucent(), light); render(model, RenderTypes.getGlowingTranslucent(), light);
// } }
public void render(BakedModel model, RenderType type, int light) { public void render(BakedModel model, RenderType type, int light) {
if (stack.isEmpty()) if (stack.isEmpty())

View File

@@ -0,0 +1,13 @@
package nl.requios.effortlessbuilding.create.foundation.mixin.accessor;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Invoker;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.Level;
@Mixin(Entity.class)
public interface EntityAccessor {
@Invoker("setLevel")
void create$callSetLevel(Level level);
}

View File

@@ -0,0 +1,13 @@
package nl.requios.effortlessbuilding.create.foundation.mixin.accessor;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Invoker;
import net.minecraft.client.Camera;
import net.minecraft.client.renderer.GameRenderer;
@Mixin(GameRenderer.class)
public interface GameRendererAccessor {
@Invoker("getFov")
double create$callGetFov(Camera camera, float partialTicks, boolean useFOVSetting);
}

View File

@@ -1,17 +1,24 @@
package nl.requios.effortlessbuilding.create.foundation.networking; package nl.requios.effortlessbuilding.create.foundation.networking;
import java.util.HashSet;
//import nl.requios.effortlessbuilding.create.AllPackets;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.Entity;
import net.minecraftforge.network.NetworkEvent.Context; import net.minecraftforge.network.NetworkEvent.Context;
import net.minecraftforge.network.PacketDistributor;
import java.util.HashSet;
public interface ISyncPersistentData { public interface ISyncPersistentData {
void onPersistentDataUpdated(); void onPersistentDataUpdated();
// default void syncPersistentDataWithTracking(Entity self) {
// AllPackets.getChannel().send(PacketDistributor.TRACKING_ENTITY.with(() -> self), new PersistentDataPacket(self));
// }
public static class PersistentDataPacket extends SimplePacketBase { public static class PersistentDataPacket extends SimplePacketBase {
private int entityId; private int entityId;

View File

@@ -0,0 +1,230 @@
package nl.requios.effortlessbuilding.create.foundation.outliner;
import java.util.Optional;
import org.joml.Vector3f;
import org.joml.Vector4f;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.VertexConsumer;
import nl.requios.effortlessbuilding.create.AllSpecialTextures;
import nl.requios.effortlessbuilding.create.foundation.render.RenderTypes;
import nl.requios.effortlessbuilding.create.foundation.render.SuperRenderTypeBuffer;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.core.Direction;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
public class AABBOutline extends Outline {
protected AABB bb;
protected final Vector3f minPosTemp1 = new Vector3f();
protected final Vector3f maxPosTemp1 = new Vector3f();
protected final Vector4f colorTemp1 = new Vector4f();
protected final Vector3f pos0Temp = new Vector3f();
protected final Vector3f pos1Temp = new Vector3f();
protected final Vector3f pos2Temp = new Vector3f();
protected final Vector3f pos3Temp = new Vector3f();
protected final Vector3f normalTemp = new Vector3f();
protected final Vector3f originTemp = new Vector3f();
public AABBOutline(AABB bb) {
setBounds(bb);
}
public AABB getBounds() {
return bb;
}
public void setBounds(AABB bb) {
this.bb = bb;
}
@Override
public void render(PoseStack ms, SuperRenderTypeBuffer buffer, Vec3 camera, float pt) {
params.loadColor(colorTemp);
Vector4f color = colorTemp;
int lightmap = params.lightmap;
boolean disableLineNormals = params.disableLineNormals;
renderBox(ms, buffer, camera, bb, color, lightmap, disableLineNormals);
}
protected void renderBox(PoseStack ms, SuperRenderTypeBuffer buffer, Vec3 camera, AABB box, Vector4f color, int lightmap, boolean disableLineNormals) {
Vector3f minPos = minPosTemp1;
Vector3f maxPos = maxPosTemp1;
boolean cameraInside = box.contains(camera);
boolean cull = !cameraInside && !params.disableCull;
float inflate = cameraInside ? -1 / 128f : 1 / 128f;
box = box.move(camera.scale(-1));
minPos.set((float) box.minX - inflate, (float) box.minY - inflate, (float) box.minZ - inflate);
maxPos.set((float) box.maxX + inflate, (float) box.maxY + inflate, (float) box.maxZ + inflate);
renderBoxFaces(ms, buffer, cull, params.getHighlightedFace(), minPos, maxPos, color, lightmap);
float lineWidth = params.getLineWidth();
if (lineWidth == 0)
return;
VertexConsumer consumer = buffer.getBuffer(RenderTypes.getOutlineSolid());
renderBoxEdges(ms, consumer, minPos, maxPos, lineWidth, color, lightmap, disableLineNormals);
}
protected void renderBoxFaces(PoseStack ms, SuperRenderTypeBuffer buffer, boolean cull, Direction highlightedFace, Vector3f minPos, Vector3f maxPos, Vector4f color, int lightmap) {
PoseStack.Pose pose = ms.last();
renderBoxFace(pose, buffer, cull, highlightedFace, minPos, maxPos, Direction.DOWN, color, lightmap);
renderBoxFace(pose, buffer, cull, highlightedFace, minPos, maxPos, Direction.UP, color, lightmap);
renderBoxFace(pose, buffer, cull, highlightedFace, minPos, maxPos, Direction.NORTH, color, lightmap);
renderBoxFace(pose, buffer, cull, highlightedFace, minPos, maxPos, Direction.SOUTH, color, lightmap);
renderBoxFace(pose, buffer, cull, highlightedFace, minPos, maxPos, Direction.WEST, color, lightmap);
renderBoxFace(pose, buffer, cull, highlightedFace, minPos, maxPos, Direction.EAST, color, lightmap);
}
protected void renderBoxFace(PoseStack.Pose pose, SuperRenderTypeBuffer buffer, boolean cull, Direction highlightedFace, Vector3f minPos, Vector3f maxPos, Direction face, Vector4f color, int lightmap) {
boolean highlighted = face == highlightedFace;
// TODO: Presumably, the other texture should be used, but this was not noticed before so fixing it may lead to suboptimal visuals.
// Optional<AllSpecialTextures> optionalFaceTexture = highlighted ? params.hightlightedFaceTexture : params.faceTexture;
Optional<AllSpecialTextures> optionalFaceTexture = params.faceTexture;
if (!optionalFaceTexture.isPresent())
return;
AllSpecialTextures faceTexture = optionalFaceTexture.get();
RenderType renderType = RenderTypes.getOutlineTranslucent(faceTexture.getLocation(), cull);
VertexConsumer consumer = buffer.getLateBuffer(renderType);
float alphaMult = highlighted ? 1 : 0.5f;
colorTemp1.set(color.x(), color.y(), color.z(), color.w() * alphaMult);
color = colorTemp1;
renderBoxFace(pose, consumer, minPos, maxPos, face, color, lightmap);
}
protected void renderBoxFace(PoseStack.Pose pose, VertexConsumer consumer, Vector3f minPos, Vector3f maxPos, Direction face, Vector4f color, int lightmap) {
Vector3f pos0 = pos0Temp;
Vector3f pos1 = pos1Temp;
Vector3f pos2 = pos2Temp;
Vector3f pos3 = pos3Temp;
Vector3f normal = normalTemp;
float minX = minPos.x();
float minY = minPos.y();
float minZ = minPos.z();
float maxX = maxPos.x();
float maxY = maxPos.y();
float maxZ = maxPos.z();
float maxU;
float maxV;
switch (face) {
case DOWN -> {
// 0 1 2 3
pos0.set(minX, minY, maxZ);
pos1.set(minX, minY, minZ);
pos2.set(maxX, minY, minZ);
pos3.set(maxX, minY, maxZ);
maxU = maxX - minX;
maxV = maxZ - minZ;
normal.set(0, -1, 0);
}
case UP -> {
// 4 5 6 7
pos0.set(minX, maxY, minZ);
pos1.set(minX, maxY, maxZ);
pos2.set(maxX, maxY, maxZ);
pos3.set(maxX, maxY, minZ);
maxU = maxX - minX;
maxV = maxZ - minZ;
normal.set(0, 1, 0);
}
case NORTH -> {
// 7 2 1 4
pos0.set(maxX, maxY, minZ);
pos1.set(maxX, minY, minZ);
pos2.set(minX, minY, minZ);
pos3.set(minX, maxY, minZ);
maxU = maxX - minX;
maxV = maxY - minY;
normal.set(0, 0, -1);
}
case SOUTH -> {
// 5 0 3 6
pos0.set(minX, maxY, maxZ);
pos1.set(minX, minY, maxZ);
pos2.set(maxX, minY, maxZ);
pos3.set(maxX, maxY, maxZ);
maxU = maxX - minX;
maxV = maxY - minY;
normal.set(0, 0, 1);
}
case WEST -> {
// 4 1 0 5
pos0.set(minX, maxY, minZ);
pos1.set(minX, minY, minZ);
pos2.set(minX, minY, maxZ);
pos3.set(minX, maxY, maxZ);
maxU = maxZ - minZ;
maxV = maxY - minY;
normal.set(-1, 0, 0);
}
case EAST -> {
// 6 3 2 7
pos0.set(maxX, maxY, maxZ);
pos1.set(maxX, minY, maxZ);
pos2.set(maxX, minY, minZ);
pos3.set(maxX, maxY, minZ);
maxU = maxZ - minZ;
maxV = maxY - minY;
normal.set(1, 0, 0);
}
default -> {
maxU = 1;
maxV = 1;
}
}
bufferQuad(pose, consumer, pos0, pos1, pos2, pos3, color, 0, 0, maxU, maxV, lightmap, normal);
}
protected void renderBoxEdges(PoseStack ms, VertexConsumer consumer, Vector3f minPos, Vector3f maxPos, float lineWidth, Vector4f color, int lightmap, boolean disableNormals) {
Vector3f origin = originTemp;
PoseStack.Pose pose = ms.last();
float lineLengthX = maxPos.x() - minPos.x();
float lineLengthY = maxPos.y() - minPos.y();
float lineLengthZ = maxPos.z() - minPos.z();
origin.set(minPos);
bufferCuboidLine(pose, consumer, origin, Direction.EAST, lineLengthX, lineWidth, color, lightmap, disableNormals);
bufferCuboidLine(pose, consumer, origin, Direction.UP, lineLengthY, lineWidth, color, lightmap, disableNormals);
bufferCuboidLine(pose, consumer, origin, Direction.SOUTH, lineLengthZ, lineWidth, color, lightmap, disableNormals);
origin.set(maxPos.x(), minPos.y(), minPos.z());
bufferCuboidLine(pose, consumer, origin, Direction.UP, lineLengthY, lineWidth, color, lightmap, disableNormals);
bufferCuboidLine(pose, consumer, origin, Direction.SOUTH, lineLengthZ, lineWidth, color, lightmap, disableNormals);
origin.set(minPos.x(), maxPos.y(), minPos.z());
bufferCuboidLine(pose, consumer, origin, Direction.EAST, lineLengthX, lineWidth, color, lightmap, disableNormals);
bufferCuboidLine(pose, consumer, origin, Direction.SOUTH, lineLengthZ, lineWidth, color, lightmap, disableNormals);
origin.set(minPos.x(), minPos.y(), maxPos.z());
bufferCuboidLine(pose, consumer, origin, Direction.EAST, lineLengthX, lineWidth, color, lightmap, disableNormals);
bufferCuboidLine(pose, consumer, origin, Direction.UP, lineLengthY, lineWidth, color, lightmap, disableNormals);
origin.set(minPos.x(), maxPos.y(), maxPos.z());
bufferCuboidLine(pose, consumer, origin, Direction.EAST, lineLengthX, lineWidth, color, lightmap, disableNormals);
origin.set(maxPos.x(), minPos.y(), maxPos.z());
bufferCuboidLine(pose, consumer, origin, Direction.UP, lineLengthY, lineWidth, color, lightmap, disableNormals);
origin.set(maxPos.x(), maxPos.y(), minPos.z());
bufferCuboidLine(pose, consumer, origin, Direction.SOUTH, lineLengthZ, lineWidth, color, lightmap, disableNormals);
}
}

View File

@@ -0,0 +1,272 @@
package nl.requios.effortlessbuilding.create.foundation.outliner;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import org.joml.Vector3f;
import org.joml.Vector4f;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.VertexConsumer;
import nl.requios.effortlessbuilding.create.AllSpecialTextures;
import nl.requios.effortlessbuilding.create.foundation.render.RenderTypes;
import nl.requios.effortlessbuilding.create.foundation.render.SuperRenderTypeBuffer;
import nl.requios.effortlessbuilding.create.foundation.utility.Iterate;
import net.minecraft.client.renderer.RenderType;
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.world.phys.Vec3;
public class BlockClusterOutline extends Outline {
private final Cluster cluster;
protected final Vector3f pos0Temp = new Vector3f();
protected final Vector3f pos1Temp = new Vector3f();
protected final Vector3f pos2Temp = new Vector3f();
protected final Vector3f pos3Temp = new Vector3f();
protected final Vector3f normalTemp = new Vector3f();
protected final Vector3f originTemp = new Vector3f();
public BlockClusterOutline(Iterable<BlockPos> positions) {
cluster = new Cluster();
positions.forEach(cluster::include);
}
@Override
public void render(PoseStack ms, SuperRenderTypeBuffer buffer, Vec3 camera, float pt) {
params.loadColor(colorTemp);
Vector4f color = colorTemp;
int lightmap = params.lightmap;
boolean disableLineNormals = params.disableLineNormals;
renderFaces(ms, buffer, camera, pt, color, lightmap);
renderEdges(ms, buffer, camera, pt, color, lightmap, disableLineNormals);
}
protected void renderFaces(PoseStack ms, SuperRenderTypeBuffer buffer, Vec3 camera, float pt, Vector4f color, int lightmap) {
Optional<AllSpecialTextures> optionalFaceTexture = params.faceTexture;
if (!optionalFaceTexture.isPresent())
return;
if (cluster.isEmpty())
return;
ms.pushPose();
ms.translate(cluster.anchor.getX() - camera.x, cluster.anchor.getY() - camera.y,
cluster.anchor.getZ() - camera.z);
AllSpecialTextures faceTexture = optionalFaceTexture.get();
PoseStack.Pose pose = ms.last();
RenderType renderType = RenderTypes.getOutlineTranslucent(faceTexture.getLocation(), true);
VertexConsumer consumer = buffer.getLateBuffer(renderType);
cluster.visibleFaces.forEach((face, axisDirection) -> {
Direction direction = Direction.get(axisDirection, face.axis);
BlockPos pos = face.pos;
if (axisDirection == AxisDirection.POSITIVE)
pos = pos.relative(direction.getOpposite());
bufferBlockFace(pose, consumer, pos, direction, color, lightmap);
});
ms.popPose();
}
protected void renderEdges(PoseStack ms, SuperRenderTypeBuffer buffer, Vec3 camera, float pt, Vector4f color, int lightmap, boolean disableNormals) {
float lineWidth = params.getLineWidth();
if (lineWidth == 0)
return;
if (cluster.isEmpty())
return;
ms.pushPose();
ms.translate(cluster.anchor.getX() - camera.x, cluster.anchor.getY() - camera.y,
cluster.anchor.getZ() - camera.z);
PoseStack.Pose pose = ms.last();
VertexConsumer consumer = buffer.getBuffer(RenderTypes.getOutlineSolid());
cluster.visibleEdges.forEach(edge -> {
BlockPos pos = edge.pos;
Vector3f origin = originTemp;
origin.set(pos.getX(), pos.getY(), pos.getZ());
Direction direction = Direction.get(AxisDirection.POSITIVE, edge.axis);
bufferCuboidLine(pose, consumer, origin, direction, 1, lineWidth, color, lightmap, disableNormals);
});
ms.popPose();
}
public static void loadFaceData(Direction face, Vector3f pos0, Vector3f pos1, Vector3f pos2, Vector3f pos3, Vector3f normal) {
switch (face) {
case DOWN -> {
// 0 1 2 3
pos0.set(0, 0, 1);
pos1.set(0, 0, 0);
pos2.set(1, 0, 0);
pos3.set(1, 0, 1);
normal.set(0, -1, 0);
}
case UP -> {
// 4 5 6 7
pos0.set(0, 1, 0);
pos1.set(0, 1, 1);
pos2.set(1, 1, 1);
pos3.set(1, 1, 0);
normal.set(0, 1, 0);
}
case NORTH -> {
// 7 2 1 4
pos0.set(1, 1, 0);
pos1.set(1, 0, 0);
pos2.set(0, 0, 0);
pos3.set(0, 1, 0);
normal.set(0, 0, -1);
}
case SOUTH -> {
// 5 0 3 6
pos0.set(0, 1, 1);
pos1.set(0, 0, 1);
pos2.set(1, 0, 1);
pos3.set(1, 1, 1);
normal.set(0, 0, 1);
}
case WEST -> {
// 4 1 0 5
pos0.set(0, 1, 0);
pos1.set(0, 0, 0);
pos2.set(0, 0, 1);
pos3.set(0, 1, 1);
normal.set(-1, 0, 0);
}
case EAST -> {
// 6 3 2 7
pos0.set(1, 1, 1);
pos1.set(1, 0, 1);
pos2.set(1, 0, 0);
pos3.set(1, 1, 0);
normal.set(1, 0, 0);
}
}
}
public static void addPos(float x, float y, float z, Vector3f pos0, Vector3f pos1, Vector3f pos2, Vector3f pos3) {
pos0.add(x, y, z);
pos1.add(x, y, z);
pos2.add(x, y, z);
pos3.add(x, y, z);
}
protected void bufferBlockFace(PoseStack.Pose pose, VertexConsumer consumer, BlockPos pos, Direction face, Vector4f color, int lightmap) {
Vector3f pos0 = pos0Temp;
Vector3f pos1 = pos1Temp;
Vector3f pos2 = pos2Temp;
Vector3f pos3 = pos3Temp;
Vector3f normal = normalTemp;
loadFaceData(face, pos0, pos1, pos2, pos3, normal);
addPos(pos.getX() + face.getStepX() * 1 / 128f,
pos.getY() + face.getStepY() * 1 / 128f,
pos.getZ() + face.getStepZ() * 1 / 128f,
pos0, pos1, pos2, pos3);
bufferQuad(pose, consumer, pos0, pos1, pos2, pos3, color, lightmap, normal);
}
private static class Cluster {
private BlockPos anchor;
private Map<MergeEntry, AxisDirection> visibleFaces;
private Set<MergeEntry> visibleEdges;
public Cluster() {
visibleEdges = new HashSet<>();
visibleFaces = new HashMap<>();
}
public boolean isEmpty() {
return anchor == null;
}
public void include(BlockPos pos) {
if (anchor == null)
anchor = pos;
pos = pos.subtract(anchor);
// 6 FACES
for (Axis axis : Iterate.axes) {
Direction direction = Direction.get(AxisDirection.POSITIVE, axis);
for (int offset : Iterate.zeroAndOne) {
MergeEntry entry = new MergeEntry(axis, pos.relative(direction, offset));
if (visibleFaces.remove(entry) == null)
visibleFaces.put(entry, offset == 0 ? AxisDirection.NEGATIVE : AxisDirection.POSITIVE);
}
}
// 12 EDGES
for (Axis axis : Iterate.axes) {
for (Axis axis2 : Iterate.axes) {
if (axis == axis2)
continue;
for (Axis axis3 : Iterate.axes) {
if (axis == axis3)
continue;
if (axis2 == axis3)
continue;
Direction direction = Direction.get(AxisDirection.POSITIVE, axis2);
Direction direction2 = Direction.get(AxisDirection.POSITIVE, axis3);
for (int offset : Iterate.zeroAndOne) {
BlockPos entryPos = pos.relative(direction, offset);
for (int offset2 : Iterate.zeroAndOne) {
entryPos = entryPos.relative(direction2, offset2);
MergeEntry entry = new MergeEntry(axis, entryPos);
if (!visibleEdges.remove(entry))
visibleEdges.add(entry);
}
}
}
break;
}
}
}
}
private static class MergeEntry {
private Axis axis;
private BlockPos pos;
public MergeEntry(Axis axis, BlockPos pos) {
this.axis = axis;
this.pos = pos;
}
@Override
public boolean equals(Object o) {
if (this == o)
return true;
if (!(o instanceof MergeEntry))
return false;
MergeEntry other = (MergeEntry) o;
return this.axis == other.axis && this.pos.equals(other.pos);
}
@Override
public int hashCode() {
return this.pos.hashCode() * 31 + axis.ordinal();
}
}
}

View File

@@ -0,0 +1,48 @@
package nl.requios.effortlessbuilding.create.foundation.outliner;
import org.joml.Vector4f;
import com.mojang.blaze3d.vertex.PoseStack;
import nl.requios.effortlessbuilding.create.foundation.render.SuperRenderTypeBuffer;
import net.minecraft.util.Mth;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
public class ChasingAABBOutline extends AABBOutline {
AABB targetBB;
AABB prevBB;
public ChasingAABBOutline(AABB bb) {
super(bb);
prevBB = bb.inflate(0);
targetBB = bb.inflate(0);
}
public void target(AABB target) {
targetBB = target;
}
@Override
public void tick() {
prevBB = bb;
setBounds(interpolateBBs(bb, targetBB, .5f));
}
@Override
public void render(PoseStack ms, SuperRenderTypeBuffer buffer, Vec3 camera, float pt) {
params.loadColor(colorTemp);
Vector4f color = colorTemp;
int lightmap = params.lightmap;
boolean disableLineNormals = params.disableLineNormals;
renderBox(ms, buffer, camera, interpolateBBs(prevBB, bb, pt), color, lightmap, disableLineNormals);
}
private static AABB interpolateBBs(AABB current, AABB target, float pt) {
return new AABB(Mth.lerp(pt, current.minX, target.minX), Mth.lerp(pt, current.minY, target.minY),
Mth.lerp(pt, current.minZ, target.minZ), Mth.lerp(pt, current.maxX, target.maxX),
Mth.lerp(pt, current.maxY, target.maxY), Mth.lerp(pt, current.maxZ, target.maxZ));
}
}

View File

@@ -0,0 +1,39 @@
package nl.requios.effortlessbuilding.create.foundation.outliner;
import com.jozufozu.flywheel.util.transform.TransformStack;
import com.mojang.blaze3d.vertex.PoseStack;
import nl.requios.effortlessbuilding.create.foundation.render.SuperRenderTypeBuffer;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.LightTexture;
import net.minecraft.client.renderer.texture.OverlayTexture;
import net.minecraft.world.item.ItemDisplayContext;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.phys.Vec3;
public class ItemOutline extends Outline {
protected Vec3 pos;
protected ItemStack stack;
public ItemOutline(Vec3 pos, ItemStack stack) {
this.pos = pos;
this.stack = stack;
}
@Override
public void render(PoseStack ms, SuperRenderTypeBuffer buffer, Vec3 camera, float pt) {
Minecraft mc = Minecraft.getInstance();
ms.pushPose();
TransformStack.cast(ms)
.translate(pos.x - camera.x, pos.y - camera.y, pos.z - camera.z)
.scale(params.alpha);
mc.getItemRenderer().render(stack, ItemDisplayContext.FIXED, false, ms,
buffer, LightTexture.FULL_BRIGHT, OverlayTexture.NO_OVERLAY,
mc.getItemRenderer().getModel(stack, null, null, 0));
ms.popPose();
}
}

View File

@@ -0,0 +1,89 @@
package nl.requios.effortlessbuilding.create.foundation.outliner;
import org.joml.Vector3d;
import org.joml.Vector4f;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.VertexConsumer;
import nl.requios.effortlessbuilding.create.foundation.render.RenderTypes;
import nl.requios.effortlessbuilding.create.foundation.render.SuperRenderTypeBuffer;
import net.minecraft.util.Mth;
import net.minecraft.world.phys.Vec3;
public class LineOutline extends Outline {
protected final Vector3d start = new Vector3d(0, 0, 0);
protected final Vector3d end = new Vector3d(0, 0, 0);
public LineOutline set(Vector3d start, Vector3d end) {
this.start.set(start.x, start.y, start.z);
this.end.set(end.x, end.y, end.z);
return this;
}
public LineOutline set(Vec3 start, Vec3 end) {
this.start.set(start.x, start.y, start.z);
this.end.set(end.x, end.y, end.z);
return this;
}
@Override
public void render(PoseStack ms, SuperRenderTypeBuffer buffer, Vec3 camera, float pt) {
float width = params.getLineWidth();
if (width == 0)
return;
VertexConsumer consumer = buffer.getBuffer(RenderTypes.getOutlineSolid());
params.loadColor(colorTemp);
Vector4f color = colorTemp;
int lightmap = params.lightmap;
boolean disableLineNormals = params.disableLineNormals;
renderInner(ms, consumer, camera, pt, width, color, lightmap, disableLineNormals);
}
protected void renderInner(PoseStack ms, VertexConsumer consumer, Vec3 camera, float pt, float width,
Vector4f color, int lightmap, boolean disableNormals) {
bufferCuboidLine(ms, consumer, camera, start, end, width, color, lightmap, disableNormals);
}
public static class EndChasingLineOutline extends LineOutline {
private float progress = 0;
private float prevProgress = 0;
private boolean lockStart;
private final Vector3d startTemp = new Vector3d(0, 0, 0);
public EndChasingLineOutline(boolean lockStart) {
this.lockStart = lockStart;
}
public EndChasingLineOutline setProgress(float progress) {
prevProgress = this.progress;
this.progress = progress;
return this;
}
@Override
protected void renderInner(PoseStack ms, VertexConsumer consumer, Vec3 camera, float pt, float width,
Vector4f color, int lightmap, boolean disableNormals) {
float distanceToTarget = Mth.lerp(pt, prevProgress, progress);
Vector3d end;
if (lockStart) {
end = this.start;
} else {
end = this.end;
distanceToTarget = 1 - distanceToTarget;
}
Vector3d start = this.startTemp;
double x = (this.start.x - end.x) * distanceToTarget + end.x;
double y = (this.start.y - end.y) * distanceToTarget + end.y;
double z = (this.start.z - end.z) * distanceToTarget + end.z;
start.set((float) x, (float) y, (float) z);
bufferCuboidLine(ms, consumer, camera, start, end, width, color, lightmap, disableNormals);
}
}
}

View File

@@ -0,0 +1,601 @@
package nl.requios.effortlessbuilding.create.foundation.outliner;
import java.util.Optional;
import javax.annotation.Nullable;
import org.joml.Matrix3f;
import org.joml.Matrix4f;
import org.joml.Vector3d;
import org.joml.Vector3f;
import org.joml.Vector4f;
import com.jozufozu.flywheel.util.transform.TransformStack;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.VertexConsumer;
import nl.requios.effortlessbuilding.create.AllSpecialTextures;
import nl.requios.effortlessbuilding.create.foundation.render.SuperRenderTypeBuffer;
import nl.requios.effortlessbuilding.create.foundation.utility.AngleHelper;
import nl.requios.effortlessbuilding.create.foundation.utility.Color;
import net.minecraft.client.renderer.LightTexture;
import net.minecraft.client.renderer.texture.OverlayTexture;
import net.minecraft.core.Direction;
import net.minecraft.util.Mth;
import net.minecraft.world.phys.Vec3;
public abstract class Outline {
protected final OutlineParams params;
protected final Vector4f colorTemp = new Vector4f();
protected final Vector3f diffPosTemp = new Vector3f();
protected final Vector3f minPosTemp = new Vector3f();
protected final Vector3f maxPosTemp = new Vector3f();
protected final Vector4f posTransformTemp = new Vector4f();
protected final Vector3f normalTransformTemp = new Vector3f();
public Outline() {
params = new OutlineParams();
}
public OutlineParams getParams() {
return params;
}
public abstract void render(PoseStack ms, SuperRenderTypeBuffer buffer, Vec3 camera, float pt);
public void tick() {}
public void bufferCuboidLine(PoseStack poseStack, VertexConsumer consumer, Vec3 camera, Vector3d start, Vector3d end,
float width, Vector4f color, int lightmap, boolean disableNormals) {
Vector3f diff = this.diffPosTemp;
diff.set((float) (end.x - start.x), (float) (end.y - start.y), (float) (end.z - start.z));
float length = Mth.sqrt(diff.x() * diff.x() + diff.y() * diff.y() + diff.z() * diff.z());
float hAngle = AngleHelper.deg(Mth.atan2(diff.x(), diff.z()));
float hDistance = Mth.sqrt(diff.x() * diff.x() + diff.z() * diff.z());
float vAngle = AngleHelper.deg(Mth.atan2(hDistance, diff.y())) - 90;
poseStack.pushPose();
TransformStack.cast(poseStack)
.translate(start.x - camera.x, start.y - camera.y, start.z - camera.z)
.rotateY(hAngle)
.rotateX(vAngle);
bufferCuboidLine(poseStack.last(), consumer, new Vector3f(), Direction.SOUTH, length, width, color, lightmap,
disableNormals);
poseStack.popPose();
}
public void bufferCuboidLine(PoseStack.Pose pose, VertexConsumer consumer, Vector3f origin, Direction direction,
float length, float width, Vector4f color, int lightmap, boolean disableNormals) {
Vector3f minPos = minPosTemp;
Vector3f maxPos = maxPosTemp;
float halfWidth = width / 2;
minPos.set(origin.x() - halfWidth, origin.y() - halfWidth, origin.z() - halfWidth);
maxPos.set(origin.x() + halfWidth, origin.y() + halfWidth, origin.z() + halfWidth);
switch (direction) {
case DOWN -> {
minPos.add(0, -length, 0);
}
case UP -> {
maxPos.add(0, length, 0);
}
case NORTH -> {
minPos.add(0, 0, -length);
}
case SOUTH -> {
maxPos.add(0, 0, length);
}
case WEST -> {
minPos.add(-length, 0, 0);
}
case EAST -> {
maxPos.add(length, 0, 0);
}
}
bufferCuboid(pose, consumer, minPos, maxPos, color, lightmap, disableNormals);
}
public void bufferCuboid(PoseStack.Pose pose, VertexConsumer consumer, Vector3f minPos, Vector3f maxPos,
Vector4f color, int lightmap, boolean disableNormals) {
Vector4f posTransformTemp = this.posTransformTemp;
Vector3f normalTransformTemp = this.normalTransformTemp;
float minX = minPos.x();
float minY = minPos.y();
float minZ = minPos.z();
float maxX = maxPos.x();
float maxY = maxPos.y();
float maxZ = maxPos.z();
Matrix4f posMatrix = pose.pose();
posTransformTemp.set(minX, minY, maxZ, 1);
posTransformTemp.mul(posMatrix);
double x0 = posTransformTemp.x();
double y0 = posTransformTemp.y();
double z0 = posTransformTemp.z();
posTransformTemp.set(minX, minY, minZ, 1);
posTransformTemp.mul(posMatrix);
double x1 = posTransformTemp.x();
double y1 = posTransformTemp.y();
double z1 = posTransformTemp.z();
posTransformTemp.set(maxX, minY, minZ, 1);
posTransformTemp.mul(posMatrix);
double x2 = posTransformTemp.x();
double y2 = posTransformTemp.y();
double z2 = posTransformTemp.z();
posTransformTemp.set(maxX, minY, maxZ, 1);
posTransformTemp.mul(posMatrix);
double x3 = posTransformTemp.x();
double y3 = posTransformTemp.y();
double z3 = posTransformTemp.z();
posTransformTemp.set(minX, maxY, minZ, 1);
posTransformTemp.mul(posMatrix);
double x4 = posTransformTemp.x();
double y4 = posTransformTemp.y();
double z4 = posTransformTemp.z();
posTransformTemp.set(minX, maxY, maxZ, 1);
posTransformTemp.mul(posMatrix);
double x5 = posTransformTemp.x();
double y5 = posTransformTemp.y();
double z5 = posTransformTemp.z();
posTransformTemp.set(maxX, maxY, maxZ, 1);
posTransformTemp.mul(posMatrix);
double x6 = posTransformTemp.x();
double y6 = posTransformTemp.y();
double z6 = posTransformTemp.z();
posTransformTemp.set(maxX, maxY, minZ, 1);
posTransformTemp.mul(posMatrix);
double x7 = posTransformTemp.x();
double y7 = posTransformTemp.y();
double z7 = posTransformTemp.z();
float r = color.x();
float g = color.y();
float b = color.z();
float a = color.w();
Matrix3f normalMatrix = pose.normal();
// down
if (disableNormals) {
normalTransformTemp.set(0, 1, 0);
} else {
normalTransformTemp.set(0, -1, 0);
}
normalTransformTemp.mul(normalMatrix);
float nx0 = normalTransformTemp.x();
float ny0 = normalTransformTemp.y();
float nz0 = normalTransformTemp.z();
consumer.vertex(x0, y0, z0)
.color(r, g, b, a)
.uv(0, 0)
.overlayCoords(OverlayTexture.NO_OVERLAY)
.uv2(lightmap)
.normal(nx0, ny0, nz0)
.endVertex();
consumer.vertex(x1, y1, z1)
.color(r, g, b, a)
.uv(0, 1)
.overlayCoords(OverlayTexture.NO_OVERLAY)
.uv2(lightmap)
.normal(nx0, ny0, nz0)
.endVertex();
consumer.vertex(x2, y2, z2)
.color(r, g, b, a)
.uv(1, 1)
.overlayCoords(OverlayTexture.NO_OVERLAY)
.uv2(lightmap)
.normal(nx0, ny0, nz0)
.endVertex();
consumer.vertex(x3, y3, z3)
.color(r, g, b, a)
.uv(1, 0)
.overlayCoords(OverlayTexture.NO_OVERLAY)
.uv2(lightmap)
.normal(nx0, ny0, nz0)
.endVertex();
// up
normalTransformTemp.set(0, 1, 0);
normalTransformTemp.mul(normalMatrix);
float nx1 = normalTransformTemp.x();
float ny1 = normalTransformTemp.y();
float nz1 = normalTransformTemp.z();
consumer.vertex(x4, y4, z4)
.color(r, g, b, a)
.uv(0, 0)
.overlayCoords(OverlayTexture.NO_OVERLAY)
.uv2(lightmap)
.normal(nx1, ny1, nz1)
.endVertex();
consumer.vertex(x5, y5, z5)
.color(r, g, b, a)
.uv(0, 1)
.overlayCoords(OverlayTexture.NO_OVERLAY)
.uv2(lightmap)
.normal(nx1, ny1, nz1)
.endVertex();
consumer.vertex(x6, y6, z6)
.color(r, g, b, a)
.uv(1, 1)
.overlayCoords(OverlayTexture.NO_OVERLAY)
.uv2(lightmap)
.normal(nx1, ny1, nz1)
.endVertex();
consumer.vertex(x7, y7, z7)
.color(r, g, b, a)
.uv(1, 0)
.overlayCoords(OverlayTexture.NO_OVERLAY)
.uv2(lightmap)
.normal(nx1, ny1, nz1)
.endVertex();
// north
if (disableNormals) {
normalTransformTemp.set(0, 1, 0);
} else {
normalTransformTemp.set(0, 0, -1);
}
normalTransformTemp.mul(normalMatrix);
float nx2 = normalTransformTemp.x();
float ny2 = normalTransformTemp.y();
float nz2 = normalTransformTemp.z();
consumer.vertex(x7, y7, z7)
.color(r, g, b, a)
.uv(0, 0)
.overlayCoords(OverlayTexture.NO_OVERLAY)
.uv2(lightmap)
.normal(nx2, ny2, nz2)
.endVertex();
consumer.vertex(x2, y2, z2)
.color(r, g, b, a)
.uv(0, 1)
.overlayCoords(OverlayTexture.NO_OVERLAY)
.uv2(lightmap)
.normal(nx2, ny2, nz2)
.endVertex();
consumer.vertex(x1, y1, z1)
.color(r, g, b, a)
.uv(1, 1)
.overlayCoords(OverlayTexture.NO_OVERLAY)
.uv2(lightmap)
.normal(nx2, ny2, nz2)
.endVertex();
consumer.vertex(x4, y4, z4)
.color(r, g, b, a)
.uv(1, 0)
.overlayCoords(OverlayTexture.NO_OVERLAY)
.uv2(lightmap)
.normal(nx2, ny2, nz2)
.endVertex();
// south
if (disableNormals) {
normalTransformTemp.set(0, 1, 0);
} else {
normalTransformTemp.set(0, 0, 1);
}
normalTransformTemp.mul(normalMatrix);
float nx3 = normalTransformTemp.x();
float ny3 = normalTransformTemp.y();
float nz3 = normalTransformTemp.z();
consumer.vertex(x5, y5, z5)
.color(r, g, b, a)
.uv(0, 0)
.overlayCoords(OverlayTexture.NO_OVERLAY)
.uv2(lightmap)
.normal(nx3, ny3, nz3)
.endVertex();
consumer.vertex(x0, y0, z0)
.color(r, g, b, a)
.uv(0, 1)
.overlayCoords(OverlayTexture.NO_OVERLAY)
.uv2(lightmap)
.normal(nx3, ny3, nz3)
.endVertex();
consumer.vertex(x3, y3, z3)
.color(r, g, b, a)
.uv(1, 1)
.overlayCoords(OverlayTexture.NO_OVERLAY)
.uv2(lightmap)
.normal(nx3, ny3, nz3)
.endVertex();
consumer.vertex(x6, y6, z6)
.color(r, g, b, a)
.uv(1, 0)
.overlayCoords(OverlayTexture.NO_OVERLAY)
.uv2(lightmap)
.normal(nx3, ny3, nz3)
.endVertex();
// west
if (disableNormals) {
normalTransformTemp.set(0, 1, 0);
} else {
normalTransformTemp.set(-1, 0, 0);
}
normalTransformTemp.mul(normalMatrix);
float nx4 = normalTransformTemp.x();
float ny4 = normalTransformTemp.y();
float nz4 = normalTransformTemp.z();
consumer.vertex(x4, y4, z4)
.color(r, g, b, a)
.uv(0, 0)
.overlayCoords(OverlayTexture.NO_OVERLAY)
.uv2(lightmap)
.normal(nx4, ny4, nz4)
.endVertex();
consumer.vertex(x1, y1, z1)
.color(r, g, b, a)
.uv(0, 1)
.overlayCoords(OverlayTexture.NO_OVERLAY)
.uv2(lightmap)
.normal(nx4, ny4, nz4)
.endVertex();
consumer.vertex(x0, y0, z0)
.color(r, g, b, a)
.uv(1, 1)
.overlayCoords(OverlayTexture.NO_OVERLAY)
.uv2(lightmap)
.normal(nx4, ny4, nz4)
.endVertex();
consumer.vertex(x5, y5, z5)
.color(r, g, b, a)
.uv(1, 0)
.overlayCoords(OverlayTexture.NO_OVERLAY)
.uv2(lightmap)
.normal(nx4, ny4, nz4)
.endVertex();
// east
if (disableNormals) {
normalTransformTemp.set(0, 1, 0);
} else {
normalTransformTemp.set(1, 0, 0);
}
normalTransformTemp.mul(normalMatrix);
float nx5 = normalTransformTemp.x();
float ny5 = normalTransformTemp.y();
float nz5 = normalTransformTemp.z();
consumer.vertex(x6, y6, z6)
.color(r, g, b, a)
.uv(0, 0)
.overlayCoords(OverlayTexture.NO_OVERLAY)
.uv2(lightmap)
.normal(nx5, ny5, nz5)
.endVertex();
consumer.vertex(x3, y3, z3)
.color(r, g, b, a)
.uv(0, 1)
.overlayCoords(OverlayTexture.NO_OVERLAY)
.uv2(lightmap)
.normal(nx5, ny5, nz5)
.endVertex();
consumer.vertex(x2, y2, z2)
.color(r, g, b, a)
.uv(1, 1)
.overlayCoords(OverlayTexture.NO_OVERLAY)
.uv2(lightmap)
.normal(nx5, ny5, nz5)
.endVertex();
consumer.vertex(x7, y7, z7)
.color(r, g, b, a)
.uv(1, 0)
.overlayCoords(OverlayTexture.NO_OVERLAY)
.uv2(lightmap)
.normal(nx5, ny5, nz5)
.endVertex();
}
public void bufferQuad(PoseStack.Pose pose, VertexConsumer consumer, Vector3f pos0, Vector3f pos1, Vector3f pos2,
Vector3f pos3, Vector4f color, int lightmap, Vector3f normal) {
bufferQuad(pose, consumer, pos0, pos1, pos2, pos3, color, 0, 0, 1, 1, lightmap, normal);
}
public void bufferQuad(PoseStack.Pose pose, VertexConsumer consumer, Vector3f pos0, Vector3f pos1, Vector3f pos2,
Vector3f pos3, Vector4f color, float minU, float minV, float maxU, float maxV, int lightmap, Vector3f normal) {
Vector4f posTransformTemp = this.posTransformTemp;
Vector3f normalTransformTemp = this.normalTransformTemp;
Matrix4f posMatrix = pose.pose();
posTransformTemp.set(pos0.x(), pos0.y(), pos0.z(), 1);
posTransformTemp.mul(posMatrix);
double x0 = posTransformTemp.x();
double y0 = posTransformTemp.y();
double z0 = posTransformTemp.z();
posTransformTemp.set(pos1.x(), pos1.y(), pos1.z(), 1);
posTransformTemp.mul(posMatrix);
double x1 = posTransformTemp.x();
double y1 = posTransformTemp.y();
double z1 = posTransformTemp.z();
posTransformTemp.set(pos2.x(), pos2.y(), pos2.z(), 1);
posTransformTemp.mul(posMatrix);
double x2 = posTransformTemp.x();
double y2 = posTransformTemp.y();
double z2 = posTransformTemp.z();
posTransformTemp.set(pos3.x(), pos3.y(), pos3.z(), 1);
posTransformTemp.mul(posMatrix);
double x3 = posTransformTemp.x();
double y3 = posTransformTemp.y();
double z3 = posTransformTemp.z();
float r = color.x();
float g = color.y();
float b = color.z();
float a = color.w();
normalTransformTemp.set(normal);
normalTransformTemp.mul(pose.normal());
float nx = normalTransformTemp.x();
float ny = normalTransformTemp.y();
float nz = normalTransformTemp.z();
consumer.vertex(x0, y0, z0)
.color(r, g, b, a)
.uv(minU, minV)
.overlayCoords(OverlayTexture.NO_OVERLAY)
.uv2(lightmap)
.normal(nx, ny, nz)
.endVertex();
consumer.vertex(x1, y1, z1)
.color(r, g, b, a)
.uv(minU, maxV)
.overlayCoords(OverlayTexture.NO_OVERLAY)
.uv2(lightmap)
.normal(nx, ny, nz)
.endVertex();
consumer.vertex(x2, y2, z2)
.color(r, g, b, a)
.uv(maxU, maxV)
.overlayCoords(OverlayTexture.NO_OVERLAY)
.uv2(lightmap)
.normal(nx, ny, nz)
.endVertex();
consumer.vertex(x3, y3, z3)
.color(r, g, b, a)
.uv(maxU, minV)
.overlayCoords(OverlayTexture.NO_OVERLAY)
.uv2(lightmap)
.normal(nx, ny, nz)
.endVertex();
}
public static class OutlineParams {
protected Optional<AllSpecialTextures> faceTexture;
protected Optional<AllSpecialTextures> hightlightedFaceTexture;
protected Direction highlightedFace;
protected boolean fadeLineWidth;
protected boolean disableCull;
protected boolean disableLineNormals;
protected float alpha;
protected int lightmap;
protected Color rgb;
private float lineWidth;
public OutlineParams() {
faceTexture = hightlightedFaceTexture = Optional.empty();
alpha = 1;
lineWidth = 1 / 32f;
fadeLineWidth = true;
rgb = Color.WHITE;
lightmap = LightTexture.FULL_BRIGHT;
}
// builder
public OutlineParams colored(int color) {
rgb = new Color(color, false);
return this;
}
public OutlineParams colored(Color c) {
rgb = c.copy();
return this;
}
public OutlineParams lightmap(int light) {
lightmap = light;
return this;
}
public OutlineParams lineWidth(float width) {
this.lineWidth = width;
return this;
}
public OutlineParams withFaceTexture(AllSpecialTextures texture) {
this.faceTexture = Optional.ofNullable(texture);
return this;
}
public OutlineParams clearTextures() {
return this.withFaceTextures(null, null);
}
public OutlineParams withFaceTextures(AllSpecialTextures texture, AllSpecialTextures highlightTexture) {
this.faceTexture = Optional.ofNullable(texture);
this.hightlightedFaceTexture = Optional.ofNullable(highlightTexture);
return this;
}
public OutlineParams highlightFace(@Nullable Direction face) {
highlightedFace = face;
return this;
}
public OutlineParams disableLineNormals() {
disableLineNormals = true;
return this;
}
public OutlineParams disableCull() {
disableCull = true;
return this;
}
// getter
public float getLineWidth() {
return fadeLineWidth ? alpha * lineWidth : lineWidth;
}
public Direction getHighlightedFace() {
return highlightedFace;
}
public void loadColor(Vector4f vec) {
vec.set(rgb.getRedAsFloat(), rgb.getGreenAsFloat(), rgb.getBlueAsFloat(), rgb.getAlphaAsFloat() * alpha);
}
}
}

View File

@@ -0,0 +1,207 @@
package nl.requios.effortlessbuilding.create.foundation.outliner;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Optional;
import com.mojang.blaze3d.vertex.PoseStack;
//import nl.requios.effortlessbuilding.create.foundation.blockEntity.behaviour.ValueBox;
import nl.requios.effortlessbuilding.create.foundation.outliner.LineOutline.EndChasingLineOutline;
import nl.requios.effortlessbuilding.create.foundation.outliner.Outline.OutlineParams;
import nl.requios.effortlessbuilding.create.foundation.render.SuperRenderTypeBuffer;
import net.minecraft.core.BlockPos;
import net.minecraft.util.Mth;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
public class Outliner {
private final Map<Object, OutlineEntry> outlines = Collections.synchronizedMap(new HashMap<>());
private final Map<Object, OutlineEntry> outlinesView = Collections.unmodifiableMap(outlines);
// Facade
// public OutlineParams showValueBox(Object slot, ValueBox box) {
// outlines.put(slot, new OutlineEntry(box));
// return box.getParams();
// }
public OutlineParams showLine(Object slot, Vec3 start, Vec3 end) {
if (!outlines.containsKey(slot)) {
LineOutline outline = new LineOutline();
addOutline(slot, outline);
}
OutlineEntry entry = outlines.get(slot);
entry.ticksTillRemoval = 1;
((LineOutline) entry.outline).set(start, end);
return entry.outline.getParams();
}
public OutlineParams endChasingLine(Object slot, Vec3 start, Vec3 end, float chasingProgress, boolean lockStart) {
if (!outlines.containsKey(slot)) {
EndChasingLineOutline outline = new EndChasingLineOutline(lockStart);
addOutline(slot, outline);
}
OutlineEntry entry = outlines.get(slot);
entry.ticksTillRemoval = 1;
((EndChasingLineOutline) entry.outline).setProgress(chasingProgress)
.set(start, end);
return entry.outline.getParams();
}
public OutlineParams showAABB(Object slot, AABB bb, int ttl) {
createAABBOutlineIfMissing(slot, bb);
ChasingAABBOutline outline = getAndRefreshAABB(slot, ttl);
outline.prevBB = outline.targetBB = outline.bb = bb;
return outline.getParams();
}
public OutlineParams showAABB(Object slot, AABB bb) {
createAABBOutlineIfMissing(slot, bb);
ChasingAABBOutline outline = getAndRefreshAABB(slot);
outline.prevBB = outline.targetBB = outline.bb = bb;
return outline.getParams();
}
public OutlineParams chaseAABB(Object slot, AABB bb) {
createAABBOutlineIfMissing(slot, bb);
ChasingAABBOutline outline = getAndRefreshAABB(slot);
outline.targetBB = bb;
return outline.getParams();
}
public OutlineParams showCluster(Object slot, Iterable<BlockPos> selection) {
BlockClusterOutline outline = new BlockClusterOutline(selection);
addOutline(slot, outline);
return outline.getParams();
}
//
public OutlineParams showItem(Object slot, Vec3 pos, ItemStack stack) {
ItemOutline outline = new ItemOutline(pos, stack);
OutlineEntry entry = new OutlineEntry(outline);
outlines.put(slot, entry);
return entry.getOutline().getParams();
}
public void keep(Object slot) {
if (outlines.containsKey(slot))
outlines.get(slot).ticksTillRemoval = 1;
}
public void keep(Object slot, int ticks){
if (outlines.containsKey(slot))
outlines.get(slot).ticksTillRemoval = ticks;
}
public void remove(Object slot) {
outlines.remove(slot);
}
public Optional<OutlineParams> edit(Object slot) {
keep(slot);
if (outlines.containsKey(slot))
return Optional.of(outlines.get(slot)
.getOutline()
.getParams());
return Optional.empty();
}
public Map<Object, OutlineEntry> getOutlines() {
return outlinesView;
}
// Utility
private void addOutline(Object slot, Outline outline) {
outlines.put(slot, new OutlineEntry(outline));
}
private void createAABBOutlineIfMissing(Object slot, AABB bb) {
if (!outlines.containsKey(slot) || !(outlines.get(slot).outline instanceof AABBOutline)) {
ChasingAABBOutline outline = new ChasingAABBOutline(bb);
addOutline(slot, outline);
}
}
private ChasingAABBOutline getAndRefreshAABB(Object slot) {
return getAndRefreshAABB(slot, 1);
}
private ChasingAABBOutline getAndRefreshAABB(Object slot, int ttl) {
OutlineEntry entry = outlines.get(slot);
entry.ticksTillRemoval = ttl;
return (ChasingAABBOutline) entry.getOutline();
}
// Maintenance
public void tickOutlines() {
Iterator<OutlineEntry> iterator = outlines.values()
.iterator();
while (iterator.hasNext()) {
OutlineEntry entry = iterator.next();
entry.tick();
if (!entry.isAlive())
iterator.remove();
}
}
public void renderOutlines(PoseStack ms, SuperRenderTypeBuffer buffer, Vec3 camera, float pt) {
outlines.forEach((key, entry) -> {
Outline outline = entry.getOutline();
OutlineParams params = outline.getParams();
params.alpha = 1;
if (entry.isFading()) {
int prevTicks = entry.ticksTillRemoval + 1;
float fadeticks = OutlineEntry.FADE_TICKS;
float lastAlpha = prevTicks >= 0 ? 1 : 1 + (prevTicks / fadeticks);
float currentAlpha = 1 + (entry.ticksTillRemoval / fadeticks);
float alpha = Mth.lerp(pt, lastAlpha, currentAlpha);
params.alpha = alpha * alpha * alpha;
if (params.alpha < 1 / 8f)
return;
}
outline.render(ms, buffer, camera, pt);
});
}
public static class OutlineEntry {
public static final int FADE_TICKS = 8;
private final Outline outline;
private int ticksTillRemoval = 1;
public OutlineEntry(Outline outline) {
this.outline = outline;
}
public Outline getOutline() {
return outline;
}
public int getTicksTillRemoval() {
return ticksTillRemoval;
}
public boolean isAlive() {
return ticksTillRemoval >= -FADE_TICKS;
}
public boolean isFading() {
return ticksTillRemoval < 0;
}
public void tick() {
ticksTillRemoval--;
outline.tick();
}
}
}

View File

@@ -0,0 +1,31 @@
package nl.requios.effortlessbuilding.create.foundation.render;
import com.jozufozu.flywheel.core.model.ModelUtil;
import com.jozufozu.flywheel.core.model.ShadeSeparatedBufferedData;
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,117 @@
package nl.requios.effortlessbuilding.create.foundation.render;
import java.util.Iterator;
import javax.annotation.Nullable;
import org.joml.Matrix4f;
import org.joml.Vector4f;
import com.jozufozu.flywheel.backend.Backend;
import com.jozufozu.flywheel.backend.instancing.InstancedRenderRegistry;
import com.jozufozu.flywheel.config.BackendType;
import com.jozufozu.flywheel.core.virtual.VirtualRenderWorld;
import com.jozufozu.flywheel.util.transform.TransformStack;
import com.mojang.blaze3d.vertex.PoseStack;
import nl.requios.effortlessbuilding.create.Create;
import nl.requios.effortlessbuilding.create.foundation.utility.AnimationTickHolder;
import nl.requios.effortlessbuilding.create.foundation.utility.RegisteredObjects;
//import nl.requios.effortlessbuilding.create.infrastructure.config.AllConfigs;
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;
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 (Backend.getBackendType() == BackendType.INSTANCING && Backend.isFlywheelWorld(renderWorld) && InstancedRenderRegistry.shouldSkipRender(blockEntity))
continue;
BlockEntityRenderer<BlockEntity> renderer = Minecraft.getInstance().getBlockEntityRenderDispatcher().getRenderer(blockEntity);
if (renderer == null) {
iterator.remove();
continue;
}
BlockPos pos = blockEntity.getBlockPos();
ms.pushPose();
TransformStack.cast(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 " + RegisteredObjects.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;
}
}

View File

@@ -0,0 +1,89 @@
package nl.requios.effortlessbuilding.create.foundation.render;
import static net.minecraft.world.level.block.state.properties.BlockStateProperties.FACING;
import java.util.function.Supplier;
import org.apache.commons.lang3.tuple.Pair;
import com.jozufozu.flywheel.core.PartialModel;
import com.jozufozu.flywheel.util.transform.TransformStack;
import com.mojang.blaze3d.vertex.PoseStack;
import nl.requios.effortlessbuilding.create.CreateClient;
import nl.requios.effortlessbuilding.create.foundation.render.SuperByteBufferCache.Compartment;
import nl.requios.effortlessbuilding.create.foundation.utility.AngleHelper;
import net.minecraft.core.Direction;
import net.minecraft.world.level.block.state.BlockState;
public class CachedBufferer {
public static final Compartment<BlockState> GENERIC_BLOCK = new Compartment<>();
public static final Compartment<PartialModel> PARTIAL = new Compartment<>();
public static final Compartment<Pair<Direction, PartialModel>> DIRECTIONAL_PARTIAL = new Compartment<>();
public static SuperByteBuffer block(BlockState toRender) {
return block(GENERIC_BLOCK, toRender);
}
public static SuperByteBuffer block(Compartment<BlockState> compartment, BlockState toRender) {
return CreateClient.BUFFER_CACHE.get(compartment, toRender, () -> BakedModelRenderHelper.standardBlockRender(toRender));
}
public static SuperByteBuffer partial(PartialModel partial, BlockState referenceState) {
return CreateClient.BUFFER_CACHE.get(PARTIAL, partial,
() -> BakedModelRenderHelper.standardModelRender(partial.get(), referenceState));
}
public static SuperByteBuffer partial(PartialModel partial, BlockState referenceState,
Supplier<PoseStack> modelTransform) {
return CreateClient.BUFFER_CACHE.get(PARTIAL, partial,
() -> BakedModelRenderHelper.standardModelRender(partial.get(), referenceState, modelTransform.get()));
}
public static SuperByteBuffer partialFacing(PartialModel partial, BlockState referenceState) {
Direction facing = referenceState.getValue(FACING);
return partialFacing(partial, referenceState, facing);
}
public static SuperByteBuffer partialFacing(PartialModel partial, BlockState referenceState, Direction facing) {
return partialDirectional(partial, referenceState, facing,
rotateToFace(facing));
}
public static SuperByteBuffer partialFacingVertical(PartialModel partial, BlockState referenceState, Direction facing) {
return partialDirectional(partial, referenceState, facing,
rotateToFaceVertical(facing));
}
public static SuperByteBuffer partialDirectional(PartialModel partial, BlockState referenceState, Direction dir,
Supplier<PoseStack> modelTransform) {
return CreateClient.BUFFER_CACHE.get(DIRECTIONAL_PARTIAL, Pair.of(dir, partial),
() -> BakedModelRenderHelper.standardModelRender(partial.get(), referenceState, modelTransform.get()));
}
public static Supplier<PoseStack> rotateToFace(Direction facing) {
return () -> {
PoseStack stack = new PoseStack();
TransformStack.cast(stack)
.centre()
.rotateY(AngleHelper.horizontalAngle(facing))
.rotateX(AngleHelper.verticalAngle(facing))
.unCentre();
return stack;
};
}
public static Supplier<PoseStack> rotateToFaceVertical(Direction facing) {
return () -> {
PoseStack stack = new PoseStack();
TransformStack.cast(stack)
.centre()
.rotateY(AngleHelper.horizontalAngle(facing))
.rotateX(AngleHelper.verticalAngle(facing) + 90)
.unCentre();
return stack;
};
}
}

View File

@@ -0,0 +1,31 @@
package nl.requios.effortlessbuilding.create.foundation.render;
import javax.annotation.Nullable;
import com.jozufozu.flywheel.util.DiffuseLightCalculator;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
public final class ForcedDiffuseState {
private static final ThreadLocal<ObjectArrayList<DiffuseLightCalculator>> FORCED_DIFFUSE = ThreadLocal.withInitial(ObjectArrayList::new);
private ForcedDiffuseState() {
}
public static void pushCalculator(DiffuseLightCalculator calculator) {
FORCED_DIFFUSE.get().push(calculator);
}
public static void popCalculator() {
FORCED_DIFFUSE.get().pop();
}
@Nullable
public static DiffuseLightCalculator getForcedCalculator() {
ObjectArrayList<DiffuseLightCalculator> stack = FORCED_DIFFUSE.get();
if (stack.isEmpty()) {
return null;
}
return stack.top();
}
}

View File

@@ -1,24 +1,33 @@
package nl.requios.effortlessbuilding.create.foundation.render; package nl.requios.effortlessbuilding.create.foundation.render;
import java.io.IOException;
import com.mojang.blaze3d.vertex.DefaultVertexFormat; import com.mojang.blaze3d.vertex.DefaultVertexFormat;
import com.mojang.blaze3d.vertex.VertexFormat; import com.mojang.blaze3d.vertex.VertexFormat;
import nl.requios.effortlessbuilding.create.AllSpecialTextures; import nl.requios.effortlessbuilding.create.AllSpecialTextures;
import nl.requios.effortlessbuilding.create.Create; import nl.requios.effortlessbuilding.create.Create;
import net.minecraft.client.renderer.RenderStateShard; import net.minecraft.client.renderer.RenderStateShard;
import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.ShaderInstance;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.packs.resources.ResourceProvider;
import net.minecraft.world.inventory.InventoryMenu; import net.minecraft.world.inventory.InventoryMenu;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.client.event.RegisterShadersEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
// TODO 1.17: use custom shaders instead of vanilla ones // TODO 1.17: use custom shaders instead of vanilla ones
public class RenderTypes extends RenderStateShard { public class RenderTypes extends RenderStateShard {
// public static final ShaderStateShard GLOWING_SHADER = new ShaderStateShard(() -> Shaders.glowingShader); public static final RenderStateShard.ShaderStateShard GLOWING_SHADER = new RenderStateShard.ShaderStateShard(() -> Shaders.glowingShader);
private static final RenderType OUTLINE_SOLID = private static final RenderType OUTLINE_SOLID =
RenderType.create(createLayerName("outline_solid"), DefaultVertexFormat.NEW_ENTITY, VertexFormat.Mode.QUADS, 256, false, RenderType.create(createLayerName("outline_solid"), DefaultVertexFormat.NEW_ENTITY, VertexFormat.Mode.QUADS, 256, false,
false, RenderType.CompositeState.builder() false, RenderType.CompositeState.builder()
.setShaderState(RENDERTYPE_ENTITY_SOLID_SHADER) .setShaderState(RENDERTYPE_ENTITY_SOLID_SHADER)
.setTextureState(new TextureStateShard(AllSpecialTextures.BLANK.getLocation(), false, false)) .setTextureState(new RenderStateShard.TextureStateShard(AllSpecialTextures.BLANK.getLocation(), false, false))
.setCullState(CULL) .setCullState(CULL)
.setLightmapState(LIGHTMAP) .setLightmapState(LIGHTMAP)
.setOverlayState(OVERLAY) .setOverlayState(OVERLAY)
@@ -32,7 +41,7 @@ public class RenderTypes extends RenderStateShard {
return RenderType.create(createLayerName("outline_translucent" + (cull ? "_cull" : "")), return RenderType.create(createLayerName("outline_translucent" + (cull ? "_cull" : "")),
DefaultVertexFormat.NEW_ENTITY, VertexFormat.Mode.QUADS, 256, false, true, RenderType.CompositeState.builder() DefaultVertexFormat.NEW_ENTITY, VertexFormat.Mode.QUADS, 256, false, true, RenderType.CompositeState.builder()
.setShaderState(cull ? RENDERTYPE_ENTITY_TRANSLUCENT_CULL_SHADER : RENDERTYPE_ENTITY_TRANSLUCENT_SHADER) .setShaderState(cull ? RENDERTYPE_ENTITY_TRANSLUCENT_CULL_SHADER : RENDERTYPE_ENTITY_TRANSLUCENT_SHADER)
.setTextureState(new TextureStateShard(texture, false, false)) .setTextureState(new RenderStateShard.TextureStateShard(texture, false, false))
.setTransparencyState(TRANSLUCENT_TRANSPARENCY) .setTransparencyState(TRANSLUCENT_TRANSPARENCY)
.setCullState(cull ? CULL : NO_CULL) .setCullState(cull ? CULL : NO_CULL)
.setLightmapState(LIGHTMAP) .setLightmapState(LIGHTMAP)
@@ -41,38 +50,38 @@ public class RenderTypes extends RenderStateShard {
.createCompositeState(false)); .createCompositeState(false));
} }
// public static RenderType getGlowingSolid(ResourceLocation texture) { public static RenderType getGlowingSolid(ResourceLocation texture) {
// return RenderType.create(createLayerName("glowing_solid"), DefaultVertexFormat.NEW_ENTITY, VertexFormat.Mode.QUADS, 256, return RenderType.create(createLayerName("glowing_solid"), DefaultVertexFormat.NEW_ENTITY, VertexFormat.Mode.QUADS, 256,
// true, false, RenderType.CompositeState.builder() true, false, RenderType.CompositeState.builder()
// .setShaderState(GLOWING_SHADER) .setShaderState(GLOWING_SHADER)
// .setTextureState(new TextureStateShard(texture, false, false)) .setTextureState(new RenderStateShard.TextureStateShard(texture, false, false))
// .setCullState(CULL) .setCullState(CULL)
// .setLightmapState(LIGHTMAP) .setLightmapState(LIGHTMAP)
// .setOverlayState(OVERLAY) .setOverlayState(OVERLAY)
// .createCompositeState(true)); .createCompositeState(true));
// } }
//
// private static final RenderType GLOWING_SOLID_DEFAULT = getGlowingSolid(InventoryMenu.BLOCK_ATLAS);
//
// public static RenderType getGlowingSolid() {
// return GLOWING_SOLID_DEFAULT;
// }
// public static RenderType getGlowingTranslucent(ResourceLocation texture) { private static final RenderType GLOWING_SOLID_DEFAULT = getGlowingSolid(InventoryMenu.BLOCK_ATLAS);
// return RenderType.create(createLayerName("glowing_translucent"), DefaultVertexFormat.NEW_ENTITY, VertexFormat.Mode.QUADS,
// 256, true, true, RenderType.CompositeState.builder() public static RenderType getGlowingSolid() {
// .setShaderState(GLOWING_SHADER) return GLOWING_SOLID_DEFAULT;
// .setTextureState(new TextureStateShard(texture, false, false)) }
// .setTransparencyState(TRANSLUCENT_TRANSPARENCY)
// .setLightmapState(LIGHTMAP) public static RenderType getGlowingTranslucent(ResourceLocation texture) {
// .setOverlayState(OVERLAY) return RenderType.create(createLayerName("glowing_translucent"), DefaultVertexFormat.NEW_ENTITY, VertexFormat.Mode.QUADS,
// .createCompositeState(true)); 256, true, true, RenderType.CompositeState.builder()
// } .setShaderState(GLOWING_SHADER)
.setTextureState(new RenderStateShard.TextureStateShard(texture, false, false))
.setTransparencyState(TRANSLUCENT_TRANSPARENCY)
.setLightmapState(LIGHTMAP)
.setOverlayState(OVERLAY)
.createCompositeState(true));
}
private static final RenderType ADDITIVE = RenderType.create(createLayerName("additive"), DefaultVertexFormat.BLOCK, private static final RenderType ADDITIVE = RenderType.create(createLayerName("additive"), DefaultVertexFormat.BLOCK,
VertexFormat.Mode.QUADS, 256, true, true, RenderType.CompositeState.builder() VertexFormat.Mode.QUADS, 256, true, true, RenderType.CompositeState.builder()
.setShaderState(RENDERTYPE_SOLID_SHADER) .setShaderState(RENDERTYPE_SOLID_SHADER)
.setTextureState(new TextureStateShard(InventoryMenu.BLOCK_ATLAS, false, false)) .setTextureState(new RenderStateShard.TextureStateShard(InventoryMenu.BLOCK_ATLAS, false, false))
.setTransparencyState(ADDITIVE_TRANSPARENCY) .setTransparencyState(ADDITIVE_TRANSPARENCY)
.setCullState(NO_CULL) .setCullState(NO_CULL)
.setLightmapState(LIGHTMAP) .setLightmapState(LIGHTMAP)
@@ -83,11 +92,11 @@ public class RenderTypes extends RenderStateShard {
return ADDITIVE; return ADDITIVE;
} }
// private static final RenderType GLOWING_TRANSLUCENT_DEFAULT = getGlowingTranslucent(InventoryMenu.BLOCK_ATLAS); private static final RenderType GLOWING_TRANSLUCENT_DEFAULT = getGlowingTranslucent(InventoryMenu.BLOCK_ATLAS);
// public static RenderType getGlowingTranslucent() { public static RenderType getGlowingTranslucent() {
// return GLOWING_TRANSLUCENT_DEFAULT; return GLOWING_TRANSLUCENT_DEFAULT;
// } }
private static final RenderType ITEM_PARTIAL_SOLID = private static final RenderType ITEM_PARTIAL_SOLID =
RenderType.create(createLayerName("item_partial_solid"), DefaultVertexFormat.NEW_ENTITY, VertexFormat.Mode.QUADS, 256, true, RenderType.create(createLayerName("item_partial_solid"), DefaultVertexFormat.NEW_ENTITY, VertexFormat.Mode.QUADS, 256, true,
@@ -138,15 +147,15 @@ public class RenderTypes extends RenderStateShard {
super(null, null, null); super(null, null, null);
} }
// @EventBusSubscriber(value = Dist.CLIENT, bus = EventBusSubscriber.Bus.MOD) @EventBusSubscriber(value = Dist.CLIENT, bus = EventBusSubscriber.Bus.MOD)
// private static class Shaders { private static class Shaders {
// private static ShaderInstance glowingShader; private static ShaderInstance glowingShader;
//
// @SubscribeEvent @SubscribeEvent
// public static void onRegisterShaders(RegisterShadersEvent event) throws IOException { public static void onRegisterShaders(RegisterShadersEvent event) throws IOException {
// ResourceManager resourceManager = event.getResourceManager(); ResourceProvider resourceProvider = event.getResourceProvider();
// event.registerShader(new ShaderInstance(resourceManager, Create.asResource("glowing_shader"), DefaultVertexFormat.NEW_ENTITY), shader -> glowingShader = shader); event.registerShader(new ShaderInstance(resourceProvider, Create.asResource("glowing_shader"), DefaultVertexFormat.NEW_ENTITY), shader -> glowingShader = shader);
// } }
// } }
} }

View File

@@ -0,0 +1,494 @@
package nl.requios.effortlessbuilding.create.foundation.render;
import java.nio.ByteBuffer;
import java.util.function.IntPredicate;
import org.joml.Matrix3f;
import org.joml.Matrix4f;
import org.joml.Quaternionf;
import org.joml.Vector3f;
import org.joml.Vector4f;
import com.jozufozu.flywheel.api.vertex.ShadedVertexList;
import com.jozufozu.flywheel.api.vertex.VertexList;
import com.jozufozu.flywheel.backend.ShadersModHandler;
import com.jozufozu.flywheel.core.model.ShadeSeparatedBufferedData;
import com.jozufozu.flywheel.core.vertex.BlockVertexList;
import com.jozufozu.flywheel.util.DiffuseLightCalculator;
import com.jozufozu.flywheel.util.transform.TStack;
import com.jozufozu.flywheel.util.transform.Transform;
import com.mojang.blaze3d.vertex.BufferBuilder;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.VertexConsumer;
import nl.requios.effortlessbuilding.create.foundation.block.render.SpriteShiftEntry;
import nl.requios.effortlessbuilding.create.foundation.utility.Color;
import it.unimi.dsi.fastutil.longs.Long2IntMap;
import it.unimi.dsi.fastutil.longs.Long2IntOpenHashMap;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.LevelRenderer;
import net.minecraft.client.renderer.LightTexture;
import net.minecraft.client.renderer.texture.OverlayTexture;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.util.Mth;
import net.minecraft.world.level.Level;
public class SuperByteBuffer implements Transform<SuperByteBuffer>, TStack<SuperByteBuffer> {
private final VertexList template;
private final IntPredicate shadedPredicate;
// Vertex Position
private final PoseStack transforms = new PoseStack();
// Vertex Coloring
private boolean shouldColor;
private int r, g, b, a;
private boolean disableDiffuseMult;
private DiffuseLightCalculator diffuseCalculator;
// Vertex Texture Coords
private SpriteShiftFunc spriteShiftFunc;
// Vertex Overlay Color
private boolean hasOverlay;
private int overlay = OverlayTexture.NO_OVERLAY;
// Vertex Lighting
private boolean useWorldLight;
private Matrix4f lightTransform;
private boolean hasCustomLight;
private int packedLightCoords;
private boolean hybridLight;
// Vertex Normals
private boolean fullNormalTransform;
// Temporary
private static final Long2IntMap WORLD_LIGHT_CACHE = new Long2IntOpenHashMap();
public SuperByteBuffer(ByteBuffer vertexBuffer, BufferBuilder.DrawState drawState, int unshadedStartVertex) {
int vertexCount = drawState.vertexCount();
int stride = drawState.format().getVertexSize();
ShadedVertexList template = new BlockVertexList.Shaded(vertexBuffer, vertexCount, stride, unshadedStartVertex);
shadedPredicate = template::isShaded;
this.template = template;
transforms.pushPose();
}
public SuperByteBuffer(ShadeSeparatedBufferedData data) {
this(data.vertexBuffer(), data.drawState(), data.unshadedStartVertex());
}
public SuperByteBuffer(ByteBuffer vertexBuffer, BufferBuilder.DrawState drawState) {
int vertexCount = drawState.vertexCount();
int stride = drawState.format().getVertexSize();
template = new BlockVertexList(vertexBuffer, vertexCount, stride);
shadedPredicate = index -> true;
transforms.pushPose();
}
public void renderInto(PoseStack input, VertexConsumer builder) {
if (isEmpty())
return;
Matrix4f modelMat = new Matrix4f(input.last()
.pose());
Matrix4f localTransforms = transforms.last()
.pose();
modelMat.mul(localTransforms);
Matrix3f normalMat;
if (fullNormalTransform) {
normalMat = new Matrix3f(input.last()
.normal());
Matrix3f localNormalTransforms = transforms.last()
.normal();
normalMat.mul(localNormalTransforms);
} else {
normalMat = new Matrix3f(transforms.last()
.normal());
}
if (useWorldLight) {
WORLD_LIGHT_CACHE.clear();
}
final Vector4f pos = new Vector4f();
final Vector3f normal = new Vector3f();
final Vector4f lightPos = new Vector4f();
DiffuseLightCalculator diffuseCalculator = ForcedDiffuseState.getForcedCalculator();
final boolean disableDiffuseMult =
this.disableDiffuseMult || (ShadersModHandler.isShaderPackInUse() && diffuseCalculator == null);
if (diffuseCalculator == null) {
diffuseCalculator = this.diffuseCalculator;
if (diffuseCalculator == null) {
diffuseCalculator = DiffuseLightCalculator.forCurrentLevel();
}
}
final int vertexCount = template.getVertexCount();
for (int i = 0; i < vertexCount; i++) {
float x = template.getX(i);
float y = template.getY(i);
float z = template.getZ(i);
pos.set(x, y, z, 1F);
pos.mul(modelMat);
builder.vertex(pos.x(), pos.y(), pos.z());
float normalX = template.getNX(i);
float normalY = template.getNY(i);
float normalZ = template.getNZ(i);
normal.set(normalX, normalY, normalZ);
normal.mul(normalMat);
float nx = normal.x();
float ny = normal.y();
float nz = normal.z();
byte r, g, b, a;
if (shouldColor) {
r = (byte) this.r;
g = (byte) this.g;
b = (byte) this.b;
a = (byte) this.a;
} else {
r = template.getR(i);
g = template.getG(i);
b = template.getB(i);
a = template.getA(i);
}
if (disableDiffuseMult) {
builder.color(r, g, b, a);
} else {
float instanceDiffuse = diffuseCalculator.getDiffuse(nx, ny, nz, shadedPredicate.test(i));
int colorR = transformColor(r, instanceDiffuse);
int colorG = transformColor(g, instanceDiffuse);
int colorB = transformColor(b, instanceDiffuse);
builder.color(colorR, colorG, colorB, a);
}
float u = template.getU(i);
float v = template.getV(i);
if (spriteShiftFunc != null) {
spriteShiftFunc.shift(builder, u, v);
} else {
builder.uv(u, v);
}
if (hasOverlay) {
builder.overlayCoords(overlay);
}
int light;
if (useWorldLight) {
lightPos.set(((x - .5f) * 15 / 16f) + .5f, (y - .5f) * 15 / 16f + .5f, (z - .5f) * 15 / 16f + .5f, 1f);
lightPos.mul(localTransforms);
if (lightTransform != null) {
lightPos.mul(lightTransform);
}
light = getLight(Minecraft.getInstance().level, lightPos);
if (hasCustomLight) {
light = maxLight(light, packedLightCoords);
}
} else if (hasCustomLight) {
light = packedLightCoords;
} else {
light = template.getLight(i);
}
if (hybridLight) {
builder.uv2(maxLight(light, template.getLight(i)));
} else {
builder.uv2(light);
}
builder.normal(nx, ny, nz);
builder.endVertex();
}
reset();
}
public SuperByteBuffer reset() {
while (!transforms.clear())
transforms.popPose();
transforms.pushPose();
shouldColor = false;
r = 0;
g = 0;
b = 0;
a = 0;
disableDiffuseMult = false;
diffuseCalculator = null;
spriteShiftFunc = null;
hasOverlay = false;
overlay = OverlayTexture.NO_OVERLAY;
useWorldLight = false;
lightTransform = null;
hasCustomLight = false;
packedLightCoords = 0;
hybridLight = false;
fullNormalTransform = false;
return this;
}
public boolean isEmpty() {
return template.isEmpty();
}
public void delete() {
template.delete();
}
public PoseStack getTransforms() {
return transforms;
}
@Override
public SuperByteBuffer translate(double x, double y, double z) {
transforms.translate(x, y, z);
return this;
}
@Override
public SuperByteBuffer multiply(Quaternionf quaternion) {
transforms.mulPose(quaternion);
return this;
}
@Override
public SuperByteBuffer scale(float factorX, float factorY, float factorZ) {
transforms.scale(factorX, factorY, factorZ);
return this;
}
@Override
public SuperByteBuffer pushPose() {
transforms.pushPose();
return this;
}
@Override
public SuperByteBuffer popPose() {
transforms.popPose();
return this;
}
@Override
public SuperByteBuffer mulPose(Matrix4f pose) {
transforms.last()
.pose()
.mul(pose);
return this;
}
@Override
public SuperByteBuffer mulNormal(Matrix3f normal) {
transforms.last()
.normal()
.mul(normal);
return this;
}
public SuperByteBuffer transform(PoseStack stack) {
transforms.last()
.pose()
.mul(stack.last()
.pose());
transforms.last()
.normal()
.mul(stack.last()
.normal());
return this;
}
public SuperByteBuffer rotateCentered(Direction axis, float radians) {
translate(.5f, .5f, .5f).rotate(axis, radians)
.translate(-.5f, -.5f, -.5f);
return this;
}
public SuperByteBuffer rotateCentered(Quaternionf q) {
translate(.5f, .5f, .5f).multiply(q)
.translate(-.5f, -.5f, -.5f);
return this;
}
public SuperByteBuffer color(int r, int g, int b, int a) {
shouldColor = true;
this.r = r;
this.g = g;
this.b = b;
this.a = a;
return this;
}
public SuperByteBuffer color(int color) {
shouldColor = true;
r = ((color >> 16) & 0xFF);
g = ((color >> 8) & 0xFF);
b = (color & 0xFF);
a = 255;
return this;
}
public SuperByteBuffer color(Color c) {
return color(c.getRGB());
}
/**
* Prevents vertex colors from being multiplied by the diffuse value calculated
* from the final transformed normal vector. Useful for entity rendering, when
* diffuse is applied automatically later.
*/
public SuperByteBuffer disableDiffuse() {
disableDiffuseMult = true;
return this;
}
public SuperByteBuffer diffuseCalculator(DiffuseLightCalculator diffuseCalculator) {
this.diffuseCalculator = diffuseCalculator;
return this;
}
public SuperByteBuffer shiftUV(SpriteShiftEntry entry) {
this.spriteShiftFunc = (builder, u, v) -> {
builder.uv(entry.getTargetU(u), entry.getTargetV(v));
};
return this;
}
public SuperByteBuffer shiftUVScrolling(SpriteShiftEntry entry, float scrollV) {
return this.shiftUVScrolling(entry, 0, scrollV);
}
public SuperByteBuffer shiftUVScrolling(SpriteShiftEntry entry, float scrollU, float scrollV) {
this.spriteShiftFunc = (builder, u, v) -> {
float targetU = u - entry.getOriginal()
.getU0() + entry.getTarget()
.getU0()
+ scrollU;
float targetV = v - entry.getOriginal()
.getV0() + entry.getTarget()
.getV0()
+ scrollV;
builder.uv(targetU, targetV);
};
return this;
}
public SuperByteBuffer shiftUVtoSheet(SpriteShiftEntry entry, float uTarget, float vTarget, int sheetSize) {
this.spriteShiftFunc = (builder, u, v) -> {
float targetU = entry.getTarget()
.getU((SpriteShiftEntry.getUnInterpolatedU(entry.getOriginal(), u) / sheetSize) + uTarget * 16);
float targetV = entry.getTarget()
.getV((SpriteShiftEntry.getUnInterpolatedV(entry.getOriginal(), v) / sheetSize) + vTarget * 16);
builder.uv(targetU, targetV);
};
return this;
}
public SuperByteBuffer overlay() {
hasOverlay = true;
return this;
}
public SuperByteBuffer overlay(int overlay) {
hasOverlay = true;
this.overlay = overlay;
return this;
}
public SuperByteBuffer light() {
useWorldLight = true;
return this;
}
public SuperByteBuffer light(Matrix4f lightTransform) {
useWorldLight = true;
this.lightTransform = lightTransform;
return this;
}
public SuperByteBuffer light(int packedLightCoords) {
hasCustomLight = true;
this.packedLightCoords = packedLightCoords;
return this;
}
public SuperByteBuffer light(Matrix4f lightTransform, int packedLightCoords) {
light(lightTransform);
light(packedLightCoords);
return this;
}
/**
* Uses max light from calculated light (world light or custom light) and vertex
* light for the final light value. Ineffective if any other light method was
* not called.
*/
public SuperByteBuffer hybridLight() {
hybridLight = true;
return this;
}
/**
* Transforms normals not only by the local matrix stack, but also by the passed
* matrix stack.
*/
public SuperByteBuffer fullNormalTransform() {
fullNormalTransform = true;
return this;
}
public SuperByteBuffer forEntityRender() {
disableDiffuse();
overlay();
fullNormalTransform();
return this;
}
public static int transformColor(byte component, float scale) {
return Mth.clamp((int) (Byte.toUnsignedInt(component) * scale), 0, 255);
}
public static int transformColor(int component, float scale) {
return Mth.clamp((int) (component * scale), 0, 255);
}
public static int maxLight(int packedLight1, int packedLight2) {
int blockLight1 = LightTexture.block(packedLight1);
int skyLight1 = LightTexture.sky(packedLight1);
int blockLight2 = LightTexture.block(packedLight2);
int skyLight2 = LightTexture.sky(packedLight2);
return LightTexture.pack(Math.max(blockLight1, blockLight2), Math.max(skyLight1, skyLight2));
}
private static int getLight(Level world, Vector4f lightPos) {
BlockPos pos = BlockPos.containing(lightPos.x(), lightPos.y(), lightPos.z());
return WORLD_LIGHT_CACHE.computeIfAbsent(pos.asLong(), $ -> LevelRenderer.getLightColor(world, pos));
}
@FunctionalInterface
public interface SpriteShiftFunc {
void shift(VertexConsumer builder, float u, float v);
}
@FunctionalInterface
public interface VertexLighter {
int getPackedLight(float x, float y, float z);
}
}

View File

@@ -0,0 +1,56 @@
package nl.requios.effortlessbuilding.create.foundation.render;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
public class SuperByteBufferCache {
protected final Map<Compartment<?>, Cache<Object, SuperByteBuffer>> caches = new HashMap<>();
public synchronized void registerCompartment(Compartment<?> compartment) {
caches.put(compartment, CacheBuilder.newBuilder()
.<Object, SuperByteBuffer>removalListener(n -> n.getValue().delete())
.build());
}
public synchronized void registerCompartment(Compartment<?> compartment, long ticksUntilExpired) {
caches.put(compartment, CacheBuilder.newBuilder()
.expireAfterAccess(ticksUntilExpired * 50, TimeUnit.MILLISECONDS)
.<Object, SuperByteBuffer>removalListener(n -> n.getValue().delete())
.build());
}
public <T> SuperByteBuffer get(Compartment<T> compartment, T key, Callable<SuperByteBuffer> callable) {
Cache<Object, SuperByteBuffer> cache = caches.get(compartment);
if (cache != null) {
try {
return cache.get(key, callable);
} catch (ExecutionException e) {
e.printStackTrace();
}
}
return null;
}
public <T> void invalidate(Compartment<T> compartment, T key) {
caches.get(compartment).invalidate(key);
}
public <T> void invalidate(Compartment<?> compartment) {
caches.get(compartment).invalidateAll();
}
public void invalidate() {
caches.forEach((compartment, cache) -> cache.invalidateAll());
}
public static class Compartment<T> {
}
}

View File

@@ -0,0 +1,95 @@
package nl.requios.effortlessbuilding.create.foundation.render;
import java.util.SortedMap;
import com.mojang.blaze3d.vertex.BufferBuilder;
import com.mojang.blaze3d.vertex.VertexConsumer;
import it.unimi.dsi.fastutil.objects.Object2ObjectLinkedOpenHashMap;
import net.minecraft.Util;
import net.minecraft.client.renderer.ChunkBufferBuilderPack;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.Sheets;
import net.minecraft.client.resources.model.ModelBakery;
public class SuperRenderTypeBuffer implements MultiBufferSource {
private static final SuperRenderTypeBuffer INSTANCE = new SuperRenderTypeBuffer();
public static SuperRenderTypeBuffer getInstance() {
return INSTANCE;
}
private SuperRenderTypeBufferPhase earlyBuffer;
private SuperRenderTypeBufferPhase defaultBuffer;
private SuperRenderTypeBufferPhase lateBuffer;
public SuperRenderTypeBuffer() {
earlyBuffer = new SuperRenderTypeBufferPhase();
defaultBuffer = new SuperRenderTypeBufferPhase();
lateBuffer = new SuperRenderTypeBufferPhase();
}
public VertexConsumer getEarlyBuffer(RenderType type) {
return earlyBuffer.bufferSource.getBuffer(type);
}
@Override
public VertexConsumer getBuffer(RenderType type) {
return defaultBuffer.bufferSource.getBuffer(type);
}
public VertexConsumer getLateBuffer(RenderType type) {
return lateBuffer.bufferSource.getBuffer(type);
}
public void draw() {
earlyBuffer.bufferSource.endBatch();
defaultBuffer.bufferSource.endBatch();
lateBuffer.bufferSource.endBatch();
}
public void draw(RenderType type) {
earlyBuffer.bufferSource.endBatch(type);
defaultBuffer.bufferSource.endBatch(type);
lateBuffer.bufferSource.endBatch(type);
}
private static class SuperRenderTypeBufferPhase {
// Visible clones from RenderBuffers
private final ChunkBufferBuilderPack fixedBufferPack = new ChunkBufferBuilderPack();
private final SortedMap<RenderType, BufferBuilder> fixedBuffers = Util.make(new Object2ObjectLinkedOpenHashMap<>(), map -> {
map.put(Sheets.solidBlockSheet(), fixedBufferPack.builder(RenderType.solid()));
map.put(Sheets.cutoutBlockSheet(), fixedBufferPack.builder(RenderType.cutout()));
map.put(Sheets.bannerSheet(), fixedBufferPack.builder(RenderType.cutoutMipped()));
map.put(Sheets.translucentCullBlockSheet(), fixedBufferPack.builder(RenderType.translucent()));
put(map, Sheets.shieldSheet());
put(map, Sheets.bedSheet());
put(map, Sheets.shulkerBoxSheet());
put(map, Sheets.signSheet());
put(map, Sheets.chestSheet());
put(map, RenderType.translucentNoCrumbling());
put(map, RenderType.armorGlint());
put(map, RenderType.armorEntityGlint());
put(map, RenderType.glint());
put(map, RenderType.glintDirect());
put(map, RenderType.glintTranslucent());
put(map, RenderType.entityGlint());
put(map, RenderType.entityGlintDirect());
put(map, RenderType.waterMask());
put(map, RenderTypes.getOutlineSolid());
ModelBakery.DESTROY_TYPES.forEach((p_173062_) -> {
put(map, p_173062_);
});
});
private final MultiBufferSource.BufferSource bufferSource = MultiBufferSource.immediateWithBuffers(fixedBuffers, new BufferBuilder(256));
private static void put(Object2ObjectLinkedOpenHashMap<RenderType, BufferBuilder> map, RenderType type) {
map.put(type, new BufferBuilder(type.bufferSize()));
}
}
}

View File

@@ -1,5 +1,10 @@
package nl.requios.effortlessbuilding.create.foundation.utility; package nl.requios.effortlessbuilding.create.foundation.utility;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import javax.annotation.Nullable;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.world.InteractionHand; import net.minecraft.world.InteractionHand;
import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.LivingEntity;
@@ -8,10 +13,6 @@ import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import net.minecraftforge.event.ForgeEventFactory; import net.minecraftforge.event.ForgeEventFactory;
import javax.annotation.Nullable;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
public abstract class AbstractBlockBreakQueue { public abstract class AbstractBlockBreakQueue {
protected Consumer<BlockPos> makeCallbackFor(Level world, float effectChance, ItemStack toDamage, protected Consumer<BlockPos> makeCallbackFor(Level world, float effectChance, ItemStack toDamage,
@Nullable Player playerEntity, BiConsumer<BlockPos, ItemStack> drop) { @Nullable Player playerEntity, BiConsumer<BlockPos, ItemStack> drop) {

View File

@@ -1,6 +1,9 @@
package nl.requios.effortlessbuilding.create.foundation.utility; package nl.requios.effortlessbuilding.create.foundation.utility;
//import nl.requios.effortlessbuilding.create.foundation.ponder.PonderWorld;
//import nl.requios.effortlessbuilding.create.foundation.ponder.ui.PonderUI;
import nl.requios.effortlessbuilding.create.foundation.utility.worldWrappers.WrappedClientWorld; import nl.requios.effortlessbuilding.create.foundation.utility.worldWrappers.WrappedClientWorld;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.world.level.LevelAccessor; import net.minecraft.world.level.LevelAccessor;
@@ -43,7 +46,7 @@ public class AnimationTickHolder {
public static int getTicks(LevelAccessor world) { public static int getTicks(LevelAccessor world) {
if (world instanceof WrappedClientWorld) if (world instanceof WrappedClientWorld)
return getTicks(((WrappedClientWorld) world).getWrappedWorld()); return getTicks(((WrappedClientWorld) world).getWrappedWorld());
return getTicks(); return /*world instanceof PonderWorld ? PonderUI.ponderTicks : */getTicks();
} }
public static float getRenderTime(LevelAccessor world) { public static float getRenderTime(LevelAccessor world) {
@@ -51,6 +54,6 @@ public class AnimationTickHolder {
} }
public static float getPartialTicks(LevelAccessor world) { public static float getPartialTicks(LevelAccessor world) {
return getPartialTicks(); return /*world instanceof PonderWorld ? PonderUI.getPartialTicks() : */getPartialTicks();
} }
} }

View File

@@ -0,0 +1,146 @@
package nl.requios.effortlessbuilding.create.foundation.utility;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.IdentityHashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import org.jetbrains.annotations.Nullable;
import nl.requios.effortlessbuilding.create.Create;
import net.minecraft.resources.ResourceLocation;
import net.minecraftforge.registries.IForgeRegistry;
public class AttachedRegistry<K, V> {
private static final List<AttachedRegistry<?, ?>> ALL = new ArrayList<>();
protected final IForgeRegistry<K> objectRegistry;
protected final Map<ResourceLocation, V> idMap = new HashMap<>();
protected final Map<K, V> objectMap = new IdentityHashMap<>();
protected final Map<ResourceLocation, Function<K, V>> deferredRegistrations = new HashMap<>();
protected boolean unwrapped = false;
public AttachedRegistry(IForgeRegistry<K> objectRegistry) {
this.objectRegistry = objectRegistry;
ALL.add(this);
}
public void register(ResourceLocation id, V value) {
if (!unwrapped) {
idMap.put(id, value);
} else {
K object = objectRegistry.getValue(id);
if (object != null) {
objectMap.put(object, value);
} else {
Create.LOGGER.warn("Could not get object for id '" + id + "' in AttachedRegistry after unwrapping!");
}
}
}
public void register(K object, V value) {
if (unwrapped) {
objectMap.put(object, value);
} else {
ResourceLocation id = objectRegistry.getKey(object);
if (id != null) {
idMap.put(id, value);
} else {
Create.LOGGER.warn("Could not get id of object '" + object + "' in AttachedRegistry before unwrapping!");
}
}
}
public void registerDeferred(ResourceLocation id, Function<K, V> func) {
if (!unwrapped) {
deferredRegistrations.put(id, func);
} else {
K object = objectRegistry.getValue(id);
if (object != null) {
objectMap.put(object, func.apply(object));
} else {
Create.LOGGER.warn("Could not get object for id '" + id + "' in AttachedRegistry after unwrapping!");
}
}
}
public void registerDeferred(K object, Function<K, V> func) {
if (unwrapped) {
objectMap.put(object, func.apply(object));
} else {
ResourceLocation id = objectRegistry.getKey(object);
if (id != null) {
deferredRegistrations.put(id, func);
} else {
Create.LOGGER.warn("Could not get id of object '" + object + "' in AttachedRegistry before unwrapping!");
}
}
}
@Nullable
public V get(ResourceLocation id) {
if (!unwrapped) {
return idMap.get(id);
} else {
K object = objectRegistry.getValue(id);
if (object != null) {
return objectMap.get(object);
} else {
Create.LOGGER.warn("Could not get object for id '" + id + "' in AttachedRegistry after unwrapping!");
return null;
}
}
}
@Nullable
public V get(K object) {
if (unwrapped) {
return objectMap.get(object);
} else {
ResourceLocation id = objectRegistry.getKey(object);
if (id != null) {
return idMap.get(id);
} else {
Create.LOGGER.warn("Could not get id of object '" + object + "' in AttachedRegistry before unwrapping!");
return null;
}
}
}
public boolean isUnwrapped() {
return unwrapped;
}
protected void unwrap() {
deferredRegistrations.forEach((id, func) -> {
K object = objectRegistry.getValue(id);
if (object != null) {
objectMap.put(object, func.apply(object));
} else {
Create.LOGGER.warn("Could not get object for id '" + id + "' in AttachedRegistry during unwrapping!");
}
});
idMap.forEach((id, value) -> {
K object = objectRegistry.getValue(id);
if (object != null) {
objectMap.put(object, value);
} else {
Create.LOGGER.warn("Could not get object for id '" + id + "' in AttachedRegistry during unwrapping!");
}
});
deferredRegistrations.clear();
idMap.clear();
unwrapped = true;
}
public static void unwrapAll() {
for (AttachedRegistry<?, ?> registry : ALL) {
registry.unwrap();
}
}
}

View File

@@ -1,5 +1,14 @@
package nl.requios.effortlessbuilding.create.foundation.utility; package nl.requios.effortlessbuilding.create.foundation.utility;
import java.util.function.Consumer;
import javax.annotation.Nullable;
//import nl.requios.effortlessbuilding.create.AllBlocks;
//import nl.requios.effortlessbuilding.create.AllTags.AllBlockTags;
//import nl.requios.effortlessbuilding.create.content.kinetics.base.KineticBlockEntity;
//import nl.requios.effortlessbuilding.create.foundation.blockEntity.IMergeableBE;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction; import net.minecraft.core.Direction;
import net.minecraft.core.SectionPos; import net.minecraft.core.SectionPos;
@@ -38,9 +47,6 @@ import net.minecraftforge.common.IPlantable;
import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.event.level.BlockEvent; import net.minecraftforge.event.level.BlockEvent;
import javax.annotation.Nullable;
import java.util.function.Consumer;
public class BlockHelper { public class BlockHelper {
public static BlockState setZeroAge(BlockState blockState) { public static BlockState setZeroAge(BlockState blockState) {
@@ -152,11 +158,11 @@ public class BlockHelper {
float effectChance, Consumer<ItemStack> droppedItemCallback) { float effectChance, Consumer<ItemStack> droppedItemCallback) {
FluidState fluidState = world.getFluidState(pos); FluidState fluidState = world.getFluidState(pos);
BlockState state = world.getBlockState(pos); BlockState state = world.getBlockState(pos);
if (world.random.nextFloat() < effectChance) if (world.random.nextFloat() < effectChance)
world.levelEvent(2001, pos, Block.getId(state)); world.levelEvent(2001, pos, Block.getId(state));
BlockEntity tileentity = state.hasBlockEntity() ? world.getBlockEntity(pos) : null; BlockEntity blockEntity = state.hasBlockEntity() ? world.getBlockEntity(pos) : null;
if (player != null) { if (player != null) {
BlockEvent.BreakEvent event = new BlockEvent.BreakEvent(world, pos, state, player); BlockEvent.BreakEvent event = new BlockEvent.BreakEvent(world, pos, state, player);
MinecraftForge.EVENT_BUS.post(event); MinecraftForge.EVENT_BUS.post(event);
@@ -174,7 +180,7 @@ public class BlockHelper {
if (world instanceof ServerLevel && world.getGameRules() if (world instanceof ServerLevel && world.getGameRules()
.getBoolean(GameRules.RULE_DOBLOCKDROPS) && !world.restoringBlockSnapshots .getBoolean(GameRules.RULE_DOBLOCKDROPS) && !world.restoringBlockSnapshots
&& (player == null || !player.isCreative())) { && (player == null || !player.isCreative())) {
for (ItemStack itemStack : Block.getDrops(state, (ServerLevel) world, pos, tileentity, player, usedTool)) for (ItemStack itemStack : Block.getDrops(state, (ServerLevel) world, pos, blockEntity, player, usedTool))
droppedItemCallback.accept(itemStack); droppedItemCallback.accept(itemStack);
// Simulating IceBlock#playerDestroy. Not calling method directly as it would drop item // Simulating IceBlock#playerDestroy. Not calling method directly as it would drop item
@@ -184,15 +190,15 @@ public class BlockHelper {
.ultraWarm()) .ultraWarm())
return false; return false;
BlockState belowState = world.getBlockState(pos.below()); BlockState blockstate = world.getBlockState(pos.below());
if (belowState.blocksMotion() || belowState.liquid()) if (blockstate.blocksMotion() || blockstate.liquid())
world.setBlockAndUpdate(pos, Blocks.WATER.defaultBlockState()); world.setBlockAndUpdate(pos, Blocks.WATER.defaultBlockState());
return true; return true;
} }
state.spawnAfterBreak((ServerLevel) world, pos, ItemStack.EMPTY, true); state.spawnAfterBreak((ServerLevel) world, pos, ItemStack.EMPTY, true);
} }
world.setBlockAndUpdate(pos, fluidState.createLegacyBlock()); world.setBlockAndUpdate(pos, fluidState.createLegacyBlock());
return true; return true;
} }
@@ -214,7 +220,7 @@ public class BlockHelper {
LevelChunkSection chunksection = chunk.getSection(idx); LevelChunkSection chunksection = chunk.getSection(idx);
if (chunksection == null) { if (chunksection == null) {
chunksection = new LevelChunkSection(world.registryAccess() chunksection = new LevelChunkSection(world.registryAccess()
.registryOrThrow(Registries.BIOME)); .registryOrThrow(Registries.BIOME));
chunk.getSections()[idx] = chunksection; chunk.getSections()[idx] = chunksection;
} }
BlockState old = chunksection.setBlockState(SectionPos.sectionRelative(target.getX()), BlockState old = chunksection.setBlockState(SectionPos.sectionRelative(target.getX()),
@@ -227,9 +233,24 @@ public class BlockHelper {
.getBlock(), target.below()); .getBlock(), target.below());
} }
public static boolean placeSchematicBlock(Level world, Player player, BlockState state, BlockPos target, ItemStack stack, public static CompoundTag prepareBlockEntityData(BlockState blockState, BlockEntity blockEntity) {
CompoundTag data = null;
if (blockEntity == null)
return data;
/*if (AllBlockTags.SAFE_NBT.matches(blockState)) {
data = blockEntity.saveWithFullMetadata();
data = NBTProcessors.process(blockEntity, data, true);
} else */if (blockEntity instanceof IPartialSafeNBT) {
data = new CompoundTag();
((IPartialSafeNBT) blockEntity).writeSafe(data);
data = NBTProcessors.process(blockEntity, data, true);
}
return data;
}
public static void placeSchematicBlock(Level world, BlockState state, BlockPos target, ItemStack stack,
@Nullable CompoundTag data) { @Nullable CompoundTag data) {
BlockEntity existingTile = world.getBlockEntity(target); BlockEntity existingBlockEntity = world.getBlockEntity(target);
// Piston // Piston
if (state.hasProperty(BlockStateProperties.EXTENDED)) if (state.hasProperty(BlockStateProperties.EXTENDED))
@@ -257,40 +278,42 @@ public class BlockHelper {
0.0D, 0.0D, 0.0D); 0.0D, 0.0D, 0.0D);
} }
Block.dropResources(state, world, target); Block.dropResources(state, world, target);
return true; return;
} }
if (state.getBlock() instanceof BaseRailBlock) { if (state.getBlock() instanceof BaseRailBlock) {
placeRailWithoutUpdate(world, state, target); placeRailWithoutUpdate(world, state, target);
} else { } /*else if (AllBlocks.BELT.has(state)) {
world.setBlock(target, state, 2); //Changed flag from 18 to 3 world.setBlock(target, state, 2);
} */else {
world.setBlock(target, state, 2); //Changed flag from 18 to 2
} }
if (data != null) { if (data != null) {
// if (existingTile instanceof IMergeableTE mergeable) { // if (existingBlockEntity instanceof IMergeableBE mergeable) {
// BlockEntity loaded = BlockEntity.loadStatic(target, state, data); // BlockEntity loaded = BlockEntity.loadStatic(target, state, data);
// if (existingTile.getType() // if (existingBlockEntity.getType()
// .equals(loaded.getType())) { // .equals(loaded.getType())) {
// mergeable.accept(loaded); // mergeable.accept(loaded);
// return; // return;
// } // }
// } // }
BlockEntity tile = world.getBlockEntity(target); BlockEntity blockEntity = world.getBlockEntity(target);
if (tile != null) { if (blockEntity != null) {
data.putInt("x", target.getX()); data.putInt("x", target.getX());
data.putInt("y", target.getY()); data.putInt("y", target.getY());
data.putInt("z", target.getZ()); data.putInt("z", target.getZ());
// if (tile instanceof KineticTileEntity) // if (blockEntity instanceof KineticBlockEntity)
// ((KineticTileEntity) tile).warnOfMovement(); // ((KineticBlockEntity) blockEntity).warnOfMovement();
tile.load(data); blockEntity.load(data);
} }
} }
try { try {
state.getBlock().setPlacedBy(world, target, state, null, stack); state.getBlock()
} catch (Exception ignored) { .setPlacedBy(world, target, state, null, stack);
} catch (Exception e) {
} }
return true;
} }
public static double getBounceMultiplier(Block block) { public static double getBounceMultiplier(Block block) {

View File

@@ -1,6 +1,7 @@
package nl.requios.effortlessbuilding.create.foundation.utility; package nl.requios.effortlessbuilding.create.foundation.utility;
import nl.requios.effortlessbuilding.create.foundation.utility.animation.LerpedFloat; import nl.requios.effortlessbuilding.create.foundation.utility.animation.LerpedFloat;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.util.Mth; import net.minecraft.util.Mth;

View File

@@ -1,12 +1,15 @@
package nl.requios.effortlessbuilding.create.foundation.utility; package nl.requios.effortlessbuilding.create.foundation.utility;
import com.google.common.hash.Hashing; import java.util.function.UnaryOperator;
import net.minecraft.util.Mth;
import net.minecraft.world.phys.Vec3;
import org.joml.Vector3f;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import java.util.function.UnaryOperator;
import org.joml.Vector3f;
import com.google.common.hash.Hashing;
import net.minecraft.util.Mth;
import net.minecraft.world.phys.Vec3;
public class Color { public class Color {
public final static Color TRANSPARENT_BLACK = new Color(0, 0, 0, 0).setImmutable(); public final static Color TRANSPARENT_BLACK = new Color(0, 0, 0, 0).setImmutable();

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