Compare commits
31 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 4a5b669245 | |||
| a37e105434 | |||
| aeea0c00c3 | |||
| 137352674e | |||
| 4734552954 | |||
| 879c2f1ec4 | |||
| 7dc9d2a352 | |||
| cabc470ebd | |||
| 0bf1f493aa | |||
| 705bd14ee4 | |||
| 155955e49b | |||
| c76a793b18 | |||
| 50cc8501a0 | |||
| 209279e3e4 | |||
| 41239572a5 | |||
| 106ab47c3d | |||
| a84f9b60e5 | |||
| 4481e8634a | |||
| 3e432682fb | |||
| 05569c03a4 | |||
| 2d567b84be | |||
| e2a378250f | |||
| e2083a1836 | |||
| 334946ab59 | |||
| 8c9bb98125 | |||
| 726f0f3d3c | |||
| 50e5898692 | |||
| de05a5f674 | |||
| 31b57fae50 | |||
| 2f686057f3 | |||
| 3aaab94b39 |
+79
-52
@@ -12,8 +12,6 @@ plugins {
|
|||||||
|
|
||||||
// Architectury is used here only as a replacement for forge's own loom
|
// Architectury is used here only as a replacement for forge's own loom
|
||||||
id "dev.architectury.loom" version "1.6-SNAPSHOT" apply false
|
id "dev.architectury.loom" version "1.6-SNAPSHOT" apply false
|
||||||
|
|
||||||
id 'xyz.wagyourtail.jvmdowngrader' version '0.9.1' apply true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -29,17 +27,17 @@ def writeBuildGradlePredefine(List<String> mcVers, int mcIndex)
|
|||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
|
|
||||||
sb.append("# DON'T TOUCH THIS FILE, This is handled by the build script\n");
|
sb.append("# DON'T TOUCH THIS FILE, This is handled by the build script\n");
|
||||||
|
|
||||||
|
|
||||||
for (int i = 0; i < mcVers.size(); i++)
|
for (int i = 0; i < mcVers.size(); i++)
|
||||||
{
|
{
|
||||||
String verStr = mcVers[i].replace(".", "_");
|
String verStr = mcVers[i].replace(".", "_");
|
||||||
sb.append("MC_" + verStr + "=" + i.toString() + "\n");
|
sb.append("MC_" + verStr + "=" + i.toString() + "\n");
|
||||||
|
|
||||||
if (mcIndex == i)
|
if (mcIndex == i)
|
||||||
sb.append("MC_VER=" + i.toString() + "\n");
|
sb.append("MC_VER=" + i.toString() + "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Check if this is a development build
|
// Check if this is a development build
|
||||||
if (mod_version.toLowerCase().contains("dev"))
|
if (mod_version.toLowerCase().contains("dev"))
|
||||||
@@ -104,20 +102,23 @@ subprojects { p ->
|
|||||||
// Apply plugins
|
// Apply plugins
|
||||||
apply plugin: "java"
|
apply plugin: "java"
|
||||||
apply plugin: "com.github.johnrengelman.shadow"
|
apply plugin: "com.github.johnrengelman.shadow"
|
||||||
apply plugin: "xyz.wagyourtail.jvmdowngrader"
|
|
||||||
if (isMinecraftSubProject)
|
if (isMinecraftSubProject)
|
||||||
apply plugin: "systems.manifold.manifold-gradle-plugin"
|
apply plugin: "systems.manifold.manifold-gradle-plugin"
|
||||||
|
|
||||||
// Apply forge's loom
|
// Apply forge's loom
|
||||||
if ( (findProject(":forge") && p == project(":forge")) || (findProject(":neoforge") && p == project(":neoforge")) )
|
if ((findProject(":forge") && p == project(":forge")) ||
|
||||||
|
(findProject(":neoforge") && p == project(":neoforge"))
|
||||||
|
)
|
||||||
|
{
|
||||||
apply plugin: "dev.architectury.loom"
|
apply plugin: "dev.architectury.loom"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Set the manifold version (may not be required tough)
|
// Set the manifold version (may not be required tough)
|
||||||
manifold {
|
manifold {
|
||||||
manifoldVersion = rootProject.manifold_version
|
manifoldVersion = rootProject.manifold_version
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// set up custom configurations (configurations are a way to handle dependencies)
|
// set up custom configurations (configurations are a way to handle dependencies)
|
||||||
configurations {
|
configurations {
|
||||||
@@ -173,12 +174,12 @@ subprojects { p ->
|
|||||||
//=====================//
|
//=====================//
|
||||||
// shared dependencies //
|
// shared dependencies //
|
||||||
//=====================//
|
//=====================//
|
||||||
|
|
||||||
// Manifold
|
// Manifold
|
||||||
if (isMinecraftSubProject) {
|
if (isMinecraftSubProject) {
|
||||||
annotationProcessor("systems.manifold:manifold-preprocessor:${rootProject.manifold_version}")
|
annotationProcessor("systems.manifold:manifold-preprocessor:${rootProject.manifold_version}")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Log4j
|
// Log4j
|
||||||
// TODO: Change to shadowMe later to work in the standalone jar
|
// TODO: Change to shadowMe later to work in the standalone jar
|
||||||
// We cannot do this now as it would break Quilt
|
// We cannot do this now as it would break Quilt
|
||||||
@@ -190,7 +191,7 @@ subprojects { p ->
|
|||||||
forgeShadowMe("org.joml:joml:${rootProject.joml_version}")
|
forgeShadowMe("org.joml:joml:${rootProject.joml_version}")
|
||||||
else
|
else
|
||||||
implementation("org.joml:joml:${rootProject.joml_version}")
|
implementation("org.joml:joml:${rootProject.joml_version}")
|
||||||
|
|
||||||
// JUnit tests
|
// JUnit tests
|
||||||
implementation("org.junit.jupiter:junit-jupiter:5.8.2")
|
implementation("org.junit.jupiter:junit-jupiter:5.8.2")
|
||||||
implementation("org.junit.jupiter:junit-jupiter-engine:5.8.2")
|
implementation("org.junit.jupiter:junit-jupiter-engine:5.8.2")
|
||||||
@@ -200,22 +201,22 @@ subprojects { p ->
|
|||||||
// Note: MC 1.16 uses 8.2.1, and versions after use 8.5.12
|
// Note: MC 1.16 uses 8.2.1, and versions after use 8.5.12
|
||||||
// We cannot relocate this library since we call some MC classes that reference it
|
// We cannot relocate this library since we call some MC classes that reference it
|
||||||
implementation("it.unimi.dsi:fastutil:${rootProject.fastutil_version}")
|
implementation("it.unimi.dsi:fastutil:${rootProject.fastutil_version}")
|
||||||
|
|
||||||
|
|
||||||
// Compression
|
// Compression
|
||||||
forgeShadowMe("org.lz4:lz4-java:${rootProject.lz4_version}") // LZ4
|
forgeShadowMe("org.lz4:lz4-java:${rootProject.lz4_version}") // LZ4
|
||||||
forgeShadowMe("org.tukaani:xz:${rootProject.xz_version}") // LZMA
|
forgeShadowMe("org.tukaani:xz:${rootProject.xz_version}") // LZMA
|
||||||
|
|
||||||
// Sqlite Database
|
// Sqlite Database
|
||||||
forgeShadowMe("org.xerial:sqlite-jdbc:${rootProject.sqlite_jdbc_version}")
|
forgeShadowMe("org.xerial:sqlite-jdbc:${rootProject.sqlite_jdbc_version}")
|
||||||
|
|
||||||
// NightConfig (includes Toml & Json)
|
// NightConfig (includes Toml & Json)
|
||||||
forgeShadowMe("com.electronwill.night-config:toml:${rootProject.nightconfig_version}")
|
forgeShadowMe("com.electronwill.night-config:toml:${rootProject.nightconfig_version}")
|
||||||
forgeShadowMe("com.electronwill.night-config:json:${rootProject.nightconfig_version}")
|
forgeShadowMe("com.electronwill.night-config:json:${rootProject.nightconfig_version}")
|
||||||
|
|
||||||
// SVG (not needed atm)
|
// SVG (not needed atm)
|
||||||
// forgeShadowMe("com.formdev:svgSalamander:${rootProject.svgSalamander_version}")
|
// forgeShadowMe("com.formdev:svgSalamander:${rootProject.svgSalamander_version}")
|
||||||
|
|
||||||
// Netty
|
// Netty
|
||||||
// Breaks 1.16.5
|
// Breaks 1.16.5
|
||||||
//forgeShadowMe("io.netty:netty-all:${rootProject.netty_version}")
|
//forgeShadowMe("io.netty:netty-all:${rootProject.netty_version}")
|
||||||
@@ -224,9 +225,9 @@ subprojects { p ->
|
|||||||
forgeShadowMe("org.lwjgl:lwjgl-jawt:${rootProject.lwjgl_version}") {
|
forgeShadowMe("org.lwjgl:lwjgl-jawt:${rootProject.lwjgl_version}") {
|
||||||
exclude group: "org.lwjgl", module: "lwjgl" // This module is imported by Minecraft so exclude it
|
exclude group: "org.lwjgl", module: "lwjgl" // This module is imported by Minecraft so exclude it
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//==========================//
|
//==========================//
|
||||||
// conditional dependencies //
|
// conditional dependencies //
|
||||||
//==========================//
|
//==========================//
|
||||||
@@ -276,7 +277,7 @@ subprojects { p ->
|
|||||||
if (isMinecraftSubProject && p != project(":common")) {
|
if (isMinecraftSubProject && p != project(":common")) {
|
||||||
configurations.push(project.configurations.shadowCommon) // Shadow the common subproject
|
configurations.push(project.configurations.shadowCommon) // Shadow the common subproject
|
||||||
relocate "com.seibel.distanthorizons.common", "loaderCommon.${p.name}.com.seibel.distanthorizons.common" // Move the loader files to a different location
|
relocate "com.seibel.distanthorizons.common", "loaderCommon.${p.name}.com.seibel.distanthorizons.common" // Move the loader files to a different location
|
||||||
|
|
||||||
if (findProject(":fabricLike") && p != project(":fabricLike")) {
|
if (findProject(":fabricLike") && p != project(":fabricLike")) {
|
||||||
configurations.push(project.configurations.shadowFabricLike) // Shadow the fabricLike subproject
|
configurations.push(project.configurations.shadowFabricLike) // Shadow the fabricLike subproject
|
||||||
relocate "com.seibel.distanthorizons.fabriclike", "loaderCommon.${p.name}.com.seibel.distanthorizons.fabriclike" // Move the loader files to a different location
|
relocate "com.seibel.distanthorizons.fabriclike", "loaderCommon.${p.name}.com.seibel.distanthorizons.fabriclike" // Move the loader files to a different location
|
||||||
@@ -290,11 +291,11 @@ subprojects { p ->
|
|||||||
|
|
||||||
// Compression (LZ4)
|
// Compression (LZ4)
|
||||||
relocate "net.jpountz", "${librariesLocation}.jpountz"
|
relocate "net.jpountz", "${librariesLocation}.jpountz"
|
||||||
|
|
||||||
// Sqlite Database
|
// Sqlite Database
|
||||||
//At the moment, there is a bug in this library which doesnt allow it to be relocated
|
//At the moment, there is a bug in this library which doesnt allow it to be relocated
|
||||||
// relocate "org.sqlite", "${librariesLocation}.sqlite"
|
// relocate "org.sqlite", "${librariesLocation}.sqlite"
|
||||||
|
|
||||||
// JOML
|
// JOML
|
||||||
if (project.hasProperty("embed_joml") && embed_joml == "true")
|
if (project.hasProperty("embed_joml") && embed_joml == "true")
|
||||||
relocate "org.joml", "${librariesLocation}.joml"
|
relocate "org.joml", "${librariesLocation}.joml"
|
||||||
@@ -304,27 +305,14 @@ subprojects { p ->
|
|||||||
|
|
||||||
// SVG (not needed atm)
|
// SVG (not needed atm)
|
||||||
// relocate "com.kitfox.svg", "${librariesLocation}.kitfox.svg"
|
// relocate "com.kitfox.svg", "${librariesLocation}.kitfox.svg"
|
||||||
|
|
||||||
// Netty
|
// Netty
|
||||||
relocate "io.netty", "${librariesLocation}.netty"
|
relocate "io.netty", "${librariesLocation}.netty"
|
||||||
|
|
||||||
mergeServiceFiles()
|
mergeServiceFiles()
|
||||||
}
|
}
|
||||||
|
// Using jar.finalizedBy(shadowJar) causes issues so we do this scuffed bypass
|
||||||
// For downgrading the Java version of our project to match the minimum Java version required by the selected Minecraft version.
|
jar.dependsOn(shadowJar)
|
||||||
task jarDowngrade(type: xyz.wagyourtail.jvmdg.gradle.task.DowngradeJar) {
|
|
||||||
inputFile = tasks.shadowJar.archiveFile
|
|
||||||
downgradeTo = JavaVersion.toVersion(rootProject.java_version as Integer)
|
|
||||||
archiveClassifier = "downgraded-${rootProject.java_version}"
|
|
||||||
}
|
|
||||||
task apiDowngrade(type: xyz.wagyourtail.jvmdg.gradle.task.ShadeJar) {
|
|
||||||
inputFile = jarDowngrade.archiveFile
|
|
||||||
downgradeTo = JavaVersion.toVersion(rootProject.java_version as Integer)
|
|
||||||
archiveClassifier = "downgraded-${rootProject.java_version}-shaded-java-api"
|
|
||||||
}
|
|
||||||
// We're using a custom downgrade task so we disable the original downgrade tasks
|
|
||||||
downgradeJar.enabled = false
|
|
||||||
shadeDowngradedApi.enabled = false
|
|
||||||
|
|
||||||
|
|
||||||
// Put stuff from gradle.properties into the mod info
|
// Put stuff from gradle.properties into the mod info
|
||||||
@@ -364,7 +352,7 @@ subprojects { p ->
|
|||||||
// TODO: Find something we can use so we can basically re-map only when the jar is shadowed and relocated
|
// TODO: Find something we can use so we can basically re-map only when the jar is shadowed and relocated
|
||||||
// println p.tasks.findByName('shadowJar')
|
// println p.tasks.findByName('shadowJar')
|
||||||
|
|
||||||
|
|
||||||
// These "hasProperty"'s are so that they can be passed through the cli (ie in the CI)
|
// These "hasProperty"'s are so that they can be passed through the cli (ie in the CI)
|
||||||
try {
|
try {
|
||||||
if (infoGitCommit == "null")
|
if (infoGitCommit == "null")
|
||||||
@@ -400,14 +388,14 @@ subprojects { p ->
|
|||||||
fabric_incompatibility_list : fabric_incompatibility_list,
|
fabric_incompatibility_list : fabric_incompatibility_list,
|
||||||
fabric_recommend_list : fabric_recommend_list,
|
fabric_recommend_list : fabric_recommend_list,
|
||||||
]
|
]
|
||||||
|
|
||||||
// replace any properties in the sub-projects with the values defined here
|
// replace any properties in the sub-projects with the values defined here
|
||||||
inputs.properties replaceProperties
|
inputs.properties replaceProperties
|
||||||
replaceProperties.put "project", project
|
replaceProperties.put "project", project
|
||||||
filesMatching(resourceTargets) {
|
filesMatching(resourceTargets) {
|
||||||
expand replaceProperties
|
expand replaceProperties
|
||||||
}
|
}
|
||||||
|
|
||||||
intoTargets.each { target ->
|
intoTargets.each { target ->
|
||||||
if (file(target).exists()) {
|
if (file(target).exists()) {
|
||||||
copy {
|
copy {
|
||||||
@@ -443,9 +431,11 @@ subprojects { p ->
|
|||||||
jar {
|
jar {
|
||||||
from "LICENSE.txt"
|
from "LICENSE.txt"
|
||||||
manifest {
|
manifest {
|
||||||
attributes 'Implementation-Title': rootProject.mod_name,
|
attributes(
|
||||||
'Implementation-Version': rootProject.mod_version,
|
'Implementation-Title': rootProject.mod_name,
|
||||||
'Main-Class': 'com.seibel.distanthorizons.core.jar.JarMain' // When changing the main of the jar change this line
|
'Implementation-Version': rootProject.mod_version,
|
||||||
|
'Main-Class': 'com.seibel.distanthorizons.core.jar.JarMain' // When changing the main of the jar change this line
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -475,11 +465,11 @@ allprojects { p ->
|
|||||||
|
|
||||||
apply plugin: "java"
|
apply plugin: "java"
|
||||||
apply plugin: "maven-publish"
|
apply plugin: "maven-publish"
|
||||||
|
|
||||||
archivesBaseName = rootProject.mod_name
|
archivesBaseName = rootProject.mod_name
|
||||||
version = project.name + "-" + rootProject.versionStr
|
version = project.name + "-" + rootProject.versionStr
|
||||||
group = rootProject.maven_group
|
group = rootProject.maven_group
|
||||||
|
|
||||||
// this is the text that appears at the top of the overview (home) page
|
// this is the text that appears at the top of the overview (home) page
|
||||||
// and is used when bookmarking a page
|
// and is used when bookmarking a page
|
||||||
javadoc.title = rootProject.mod_name + "-" + project.name
|
javadoc.title = rootProject.mod_name + "-" + project.name
|
||||||
@@ -567,6 +557,44 @@ allprojects { p ->
|
|||||||
// TODO: If neoforged is ever needed, should we use that, or call it a forge mod?
|
// TODO: If neoforged is ever needed, should we use that, or call it a forge mod?
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Adds some dependencies that are in vanilla but not in core
|
||||||
|
if (p == project(":core")) {
|
||||||
|
OperatingSystem os = org.gradle.nativeplatform.platform.internal.DefaultNativePlatform.currentOperatingSystem;
|
||||||
|
|
||||||
|
// Set the OS lwjgl is using to the current os
|
||||||
|
project.ext.lwjglNatives = "natives-" + os.toFamilyName()
|
||||||
|
|
||||||
|
dependencies { // All of these dependencies are in Vanilla Minecraft, but we need to depend on it as we arent importing Minecraft in the core
|
||||||
|
// Imports most of lwjgl's libraries (well, only the ones that we need)
|
||||||
|
implementation platform("org.lwjgl:lwjgl-bom:${rootProject.lwjgl_version}") // TODO: Use Minecraft's version for lwjgl_version (which changes in nearly every version) instead of a hard defined version for all versions
|
||||||
|
|
||||||
|
// REMEMBER: Dont shadow stuff here, these are just the libs that are included in Minecraft so that the core can use
|
||||||
|
implementation "org.lwjgl:lwjgl"
|
||||||
|
implementation "org.lwjgl:lwjgl-assimp"
|
||||||
|
implementation "org.lwjgl:lwjgl-glfw"
|
||||||
|
implementation "org.lwjgl:lwjgl-openal"
|
||||||
|
implementation "org.lwjgl:lwjgl-opengl"
|
||||||
|
implementation "org.lwjgl:lwjgl-stb"
|
||||||
|
implementation "org.lwjgl:lwjgl-tinyfd"
|
||||||
|
runtimeOnly "org.lwjgl:lwjgl::$lwjglNatives"
|
||||||
|
runtimeOnly "org.lwjgl:lwjgl-assimp::$lwjglNatives"
|
||||||
|
runtimeOnly "org.lwjgl:lwjgl-glfw::$lwjglNatives"
|
||||||
|
runtimeOnly "org.lwjgl:lwjgl-openal::$lwjglNatives"
|
||||||
|
runtimeOnly "org.lwjgl:lwjgl-opengl::$lwjglNatives"
|
||||||
|
runtimeOnly "org.lwjgl:lwjgl-stb::$lwjglNatives"
|
||||||
|
runtimeOnly "org.lwjgl:lwjgl-tinyfd::$lwjglNatives"
|
||||||
|
implementation "org.joml:joml:${rootProject.joml_version}"
|
||||||
|
|
||||||
|
|
||||||
|
// Some other dependencies
|
||||||
|
implementation("org.jetbrains:annotations:16.0.2")
|
||||||
|
implementation("com.google.code.findbugs:jsr305:3.0.2")
|
||||||
|
implementation("com.google.common:google-collect:0.5")
|
||||||
|
implementation("com.google.guava:guava:31.1-jre")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
task copyCommonLoaderResources(type: Copy) {
|
task copyCommonLoaderResources(type: Copy) {
|
||||||
from project(":common").file("src/main/resources/${accessWidenerVersion}.distanthorizons.accesswidener")
|
from project(":common").file("src/main/resources/${accessWidenerVersion}.distanthorizons.accesswidener")
|
||||||
into(file(p.file("build/resources/main")))
|
into(file(p.file("build/resources/main")))
|
||||||
@@ -588,17 +616,16 @@ allprojects { p ->
|
|||||||
|
|
||||||
tasks.withType(JavaCompile) {
|
tasks.withType(JavaCompile) {
|
||||||
if (isMinecraftSubProject) {
|
if (isMinecraftSubProject) {
|
||||||
options.release = rootProject.java_version as Integer // Neoforge complains without this
|
options.release = rootProject.java_version as Integer
|
||||||
options.compilerArgs += ["-Xplugin:Manifold"]
|
options.compilerArgs += ["-Xplugin:Manifold"]
|
||||||
|
} else {
|
||||||
|
options.release = 8; // Core & Api should use Java 8 no matter what
|
||||||
|
//options.release = rootProject.java_version as Integer // But if you want to test some stuff, then this can be enabled
|
||||||
}
|
}
|
||||||
options.encoding = "UTF-8"
|
options.encoding = "UTF-8"
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sets the project's actual Java version (it's recommended to use this over the `options.release` method above)
|
|
||||||
java {
|
java {
|
||||||
sourceCompatibility = rootProject.java_version
|
|
||||||
targetCompatibility = rootProject.java_version
|
|
||||||
|
|
||||||
withSourcesJar()
|
withSourcesJar()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -103,7 +103,7 @@ public abstract class AbstractModInitializer
|
|||||||
LOGGER.info(ModInfo.READABLE_NAME + " Initialized");
|
LOGGER.info(ModInfo.READABLE_NAME + " Initialized");
|
||||||
ApiEventInjector.INSTANCE.fireAllEvents(DhApiAfterDhInitEvent.class, null);
|
ApiEventInjector.INSTANCE.fireAllEvents(DhApiAfterDhInitEvent.class, null);
|
||||||
|
|
||||||
this.subscribeRegisterCommandsEvent(dispatcher -> this.commandDispatcher = dispatcher);
|
this.subscribeRegisterCommandsEvent(dispatcher -> { this.commandDispatcher = dispatcher; });
|
||||||
|
|
||||||
this.subscribeServerStartingEvent(server ->
|
this.subscribeServerStartingEvent(server ->
|
||||||
{
|
{
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package com.seibel.distanthorizons.fabric.mixins.client;
|
package com.seibel.distanthorizons.common.mixins.client;
|
||||||
|
|
||||||
import com.seibel.distanthorizons.core.logging.f3.F3Screen;
|
import com.seibel.distanthorizons.core.logging.f3.F3Screen;
|
||||||
import net.minecraft.client.gui.components.DebugScreenOverlay;
|
import net.minecraft.client.gui.components.DebugScreenOverlay;
|
||||||
+1
-1
@@ -17,7 +17,7 @@
|
|||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.seibel.distanthorizons.fabric.mixins.client;
|
package com.seibel.distanthorizons.common.mixins.client;
|
||||||
|
|
||||||
import com.seibel.distanthorizons.core.config.Config;
|
import com.seibel.distanthorizons.core.config.Config;
|
||||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package com.seibel.distanthorizons.fabric.mixins.client;
|
package com.seibel.distanthorizons.common.mixins.client;
|
||||||
|
|
||||||
import com.seibel.distanthorizons.common.wrappers.DependencySetupDoneCheck;
|
import com.seibel.distanthorizons.common.wrappers.DependencySetupDoneCheck;
|
||||||
import com.seibel.distanthorizons.core.api.internal.ClientApi;
|
import com.seibel.distanthorizons.core.api.internal.ClientApi;
|
||||||
+1
-1
@@ -17,7 +17,7 @@
|
|||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.seibel.distanthorizons.fabric.mixins.client;
|
package com.seibel.distanthorizons.common.mixins.client;
|
||||||
|
|
||||||
|
|
||||||
import com.mojang.blaze3d.platform.NativeImage;
|
import com.mojang.blaze3d.platform.NativeImage;
|
||||||
+1
-1
@@ -26,6 +26,6 @@ public class DependencySetupDoneCheck
|
|||||||
// TODO move to DependencySetup
|
// TODO move to DependencySetup
|
||||||
public static boolean isDone = false;
|
public static boolean isDone = false;
|
||||||
// TODO why is this here and what is its purpose?
|
// TODO why is this here and what is its purpose?
|
||||||
public static Supplier<Boolean> getIsCurrentThreadDistantGeneratorThread = (() -> false);
|
public static Supplier<Boolean> getIsCurrentThreadDistantGeneratorThread = (() -> { return false; });
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+27
-11
@@ -102,17 +102,33 @@ public class McObjectConverter
|
|||||||
lodDirections = new EDhDirection[lodDirs.length];
|
lodDirections = new EDhDirection[lodDirs.length];
|
||||||
for (EDhDirection lodDir : lodDirs)
|
for (EDhDirection lodDir : lodDirs)
|
||||||
{
|
{
|
||||||
Direction dir = switch (lodDir.name().toUpperCase()) {
|
Direction dir;
|
||||||
case "DOWN" -> Direction.DOWN;
|
switch (lodDir.name().toUpperCase())
|
||||||
case "UP" -> Direction.UP;
|
{
|
||||||
case "NORTH" -> Direction.NORTH;
|
case "DOWN":
|
||||||
case "SOUTH" -> Direction.SOUTH;
|
dir = Direction.DOWN;
|
||||||
case "WEST" -> Direction.WEST;
|
break;
|
||||||
case "EAST" -> Direction.EAST;
|
case "UP":
|
||||||
default -> null;
|
dir = Direction.UP;
|
||||||
};
|
break;
|
||||||
|
case "NORTH":
|
||||||
if (dir == null)
|
dir = Direction.NORTH;
|
||||||
|
break;
|
||||||
|
case "SOUTH":
|
||||||
|
dir = Direction.SOUTH;
|
||||||
|
break;
|
||||||
|
case "WEST":
|
||||||
|
dir = Direction.WEST;
|
||||||
|
break;
|
||||||
|
case "EAST":
|
||||||
|
dir = Direction.EAST;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
dir = null;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dir == null)
|
||||||
{
|
{
|
||||||
throw new IllegalArgumentException("Invalid direction on init mapping: " + lodDir);
|
throw new IllegalArgumentException("Invalid direction on init mapping: " + lodDir);
|
||||||
}
|
}
|
||||||
|
|||||||
+10
-5
@@ -161,17 +161,19 @@ public class WrapperFactory implements IWrapperFactory
|
|||||||
// correct number of parameters from the API
|
// correct number of parameters from the API
|
||||||
|
|
||||||
// chunk
|
// chunk
|
||||||
if (!(objectArray[0] instanceof ChunkAccess chunk))
|
if (!(objectArray[0] instanceof ChunkAccess))
|
||||||
{
|
{
|
||||||
throw new ClassCastException(createChunkWrapperErrorMessage(objectArray));
|
throw new ClassCastException(createChunkWrapperErrorMessage(objectArray));
|
||||||
}
|
}
|
||||||
|
ChunkAccess chunk = (ChunkAccess) objectArray[0];
|
||||||
|
|
||||||
// level / light source
|
// level / light source
|
||||||
if (!(objectArray[1] instanceof Level level))
|
if (!(objectArray[1] instanceof Level))
|
||||||
{
|
{
|
||||||
throw new ClassCastException(createChunkWrapperErrorMessage(objectArray));
|
throw new ClassCastException(createChunkWrapperErrorMessage(objectArray));
|
||||||
}
|
}
|
||||||
// the level is needed for the DH level wrapper...
|
// the level is needed for the DH level wrapper...
|
||||||
|
Level level = (Level) objectArray[1];
|
||||||
// ...the LevelReader is needed for chunk lighting
|
// ...the LevelReader is needed for chunk lighting
|
||||||
LevelReader lightSource = level;
|
LevelReader lightSource = level;
|
||||||
|
|
||||||
@@ -243,10 +245,11 @@ public class WrapperFactory implements IWrapperFactory
|
|||||||
public IDhApiBiomeWrapper getBiomeWrapper(Object[] objectArray, IDhApiLevelWrapper levelWrapper)
|
public IDhApiBiomeWrapper getBiomeWrapper(Object[] objectArray, IDhApiLevelWrapper levelWrapper)
|
||||||
{
|
{
|
||||||
// confirm the API level wrapper is also a Core wrapper
|
// confirm the API level wrapper is also a Core wrapper
|
||||||
if (!(levelWrapper instanceof ILevelWrapper coreLevelWrapper))
|
if (!(levelWrapper instanceof ILevelWrapper))
|
||||||
{
|
{
|
||||||
throw new ClassCastException("Invalid ["+IDhApiLevelWrapper.class.getSimpleName()+"] value given. Level wrapper object must be one given by the DH API (it can't be a custom implementation), specifically of type ["+ILevelWrapper.class.getName()+"].");
|
throw new ClassCastException("Invalid ["+IDhApiLevelWrapper.class.getSimpleName()+"] value given. Level wrapper object must be one given by the DH API (it can't be a custom implementation), specifically of type ["+ILevelWrapper.class.getName()+"].");
|
||||||
}
|
}
|
||||||
|
ILevelWrapper coreLevelWrapper = (ILevelWrapper) levelWrapper;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -301,10 +304,11 @@ public class WrapperFactory implements IWrapperFactory
|
|||||||
public IDhApiBlockStateWrapper getBlockStateWrapper(Object[] objectArray, IDhApiLevelWrapper levelWrapper)
|
public IDhApiBlockStateWrapper getBlockStateWrapper(Object[] objectArray, IDhApiLevelWrapper levelWrapper)
|
||||||
{
|
{
|
||||||
// confirm the API level wrapper is also a Core wrapper
|
// confirm the API level wrapper is also a Core wrapper
|
||||||
if (!(levelWrapper instanceof ILevelWrapper coreLevelWrapper))
|
if (!(levelWrapper instanceof ILevelWrapper))
|
||||||
{
|
{
|
||||||
throw new ClassCastException("Invalid ["+IDhApiLevelWrapper.class.getSimpleName()+"] value given. Level wrapper object must be one given by the DH API (it can't be a custom implementation), specifically of type ["+ILevelWrapper.class.getName()+"].");
|
throw new ClassCastException("Invalid ["+IDhApiLevelWrapper.class.getSimpleName()+"] value given. Level wrapper object must be one given by the DH API (it can't be a custom implementation), specifically of type ["+ILevelWrapper.class.getName()+"].");
|
||||||
}
|
}
|
||||||
|
ILevelWrapper coreLevelWrapper = (ILevelWrapper) levelWrapper;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -313,11 +317,12 @@ public class WrapperFactory implements IWrapperFactory
|
|||||||
{
|
{
|
||||||
throw new ClassCastException(createBlockStateWrapperErrorMessage(objectArray));
|
throw new ClassCastException(createBlockStateWrapperErrorMessage(objectArray));
|
||||||
}
|
}
|
||||||
if (!(objectArray[0] instanceof BlockState blockState))
|
if (!(objectArray[0] instanceof BlockState))
|
||||||
{
|
{
|
||||||
throw new ClassCastException(createBlockStateWrapperErrorMessage(objectArray));
|
throw new ClassCastException(createBlockStateWrapperErrorMessage(objectArray));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BlockState blockState = (BlockState) objectArray[0];
|
||||||
return BlockStateWrapper.fromBlockState(blockState, coreLevelWrapper);
|
return BlockStateWrapper.fromBlockState(blockState, coreLevelWrapper);
|
||||||
#else
|
#else
|
||||||
// See preprocessor comment in createChunkWrapper() for full documentation (not a typo, check createChunkWrapper()'s else statement for full documentation)
|
// See preprocessor comment in createChunkWrapper() for full documentation (not a typo, check createChunkWrapper()'s else statement for full documentation)
|
||||||
|
|||||||
+1
-1
@@ -266,7 +266,7 @@ public class BiomeWrapper implements IBiomeWrapper
|
|||||||
}
|
}
|
||||||
return EMPTY_WRAPPER;
|
return EMPTY_WRAPPER;
|
||||||
}
|
}
|
||||||
else if (resourceLocationString.trim().isEmpty() || resourceLocationString.isEmpty())
|
else if (resourceLocationString.trim().isEmpty() || resourceLocationString.equals(""))
|
||||||
{
|
{
|
||||||
LOGGER.warn("Null biome string deserialized.");
|
LOGGER.warn("Null biome string deserialized.");
|
||||||
return EMPTY_WRAPPER;
|
return EMPTY_WRAPPER;
|
||||||
|
|||||||
+3
-4
@@ -34,7 +34,6 @@ import net.minecraft.world.level.block.Block;
|
|||||||
import net.minecraft.world.level.block.Blocks;
|
import net.minecraft.world.level.block.Blocks;
|
||||||
import net.minecraft.world.level.block.SoundType;
|
import net.minecraft.world.level.block.SoundType;
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
import net.minecraft.world.level.block.state.properties.Property;
|
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
@@ -234,7 +233,7 @@ public class BlockStateWrapper implements IBlockStateWrapper
|
|||||||
String ignoreBlockCsv = config.get();
|
String ignoreBlockCsv = config.get();
|
||||||
if (ignoreBlockCsv != null)
|
if (ignoreBlockCsv != null)
|
||||||
{
|
{
|
||||||
blockStringList.addAll(List.of(ignoreBlockCsv.split(",")));
|
blockStringList.addAll(Arrays.asList(ignoreBlockCsv.split(",")));
|
||||||
}
|
}
|
||||||
|
|
||||||
return getBlockWrappers(blockStringList, levelWrapper);
|
return getBlockWrappers(blockStringList, levelWrapper);
|
||||||
@@ -462,7 +461,7 @@ public class BlockStateWrapper implements IBlockStateWrapper
|
|||||||
// we need the final string for the concurrent hash map later
|
// we need the final string for the concurrent hash map later
|
||||||
final String finalResourceStateString = resourceStateString;
|
final String finalResourceStateString = resourceStateString;
|
||||||
|
|
||||||
if (finalResourceStateString.equals(AIR_STRING) || finalResourceStateString.isEmpty()) // the empty string shouldn't normally happen, but just in case
|
if (finalResourceStateString.equals(AIR_STRING) || finalResourceStateString.equals("")) // the empty string shouldn't normally happen, but just in case
|
||||||
{
|
{
|
||||||
return AIR;
|
return AIR;
|
||||||
}
|
}
|
||||||
@@ -603,7 +602,7 @@ public class BlockStateWrapper implements IBlockStateWrapper
|
|||||||
|
|
||||||
// alphabetically sort the list so they are always in the same order
|
// alphabetically sort the list so they are always in the same order
|
||||||
List<net.minecraft.world.level.block.state.properties.Property<?>> sortedBlockPropteryList = new ArrayList<>(blockPropertyCollection);
|
List<net.minecraft.world.level.block.state.properties.Property<?>> sortedBlockPropteryList = new ArrayList<>(blockPropertyCollection);
|
||||||
sortedBlockPropteryList.sort(Comparator.comparing(Property::getName));
|
sortedBlockPropteryList.sort((a, b) -> a.getName().compareTo(b.getName()));
|
||||||
|
|
||||||
|
|
||||||
StringBuilder stringBuilder = new StringBuilder();
|
StringBuilder stringBuilder = new StringBuilder();
|
||||||
|
|||||||
+247
-170
@@ -17,7 +17,7 @@
|
|||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.seibel.distanthorizons.common.wrappers.block.cache;
|
package com.seibel.distanthorizons.common.wrappers.block;
|
||||||
|
|
||||||
import com.seibel.distanthorizons.common.wrappers.block.BiomeWrapper;
|
import com.seibel.distanthorizons.common.wrappers.block.BiomeWrapper;
|
||||||
import com.seibel.distanthorizons.common.wrappers.block.TextureAtlasSpriteWrapper;
|
import com.seibel.distanthorizons.common.wrappers.block.TextureAtlasSpriteWrapper;
|
||||||
@@ -31,7 +31,6 @@ import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapp
|
|||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.renderer.block.model.BakedQuad;
|
import net.minecraft.client.renderer.block.model.BakedQuad;
|
||||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||||
import net.minecraft.core.BlockPos;
|
|
||||||
import net.minecraft.core.Direction;
|
import net.minecraft.core.Direction;
|
||||||
import net.minecraft.world.level.LevelReader;
|
import net.minecraft.world.level.LevelReader;
|
||||||
import net.minecraft.world.level.block.Block;
|
import net.minecraft.world.level.block.Block;
|
||||||
@@ -48,73 +47,70 @@ import org.apache.logging.log4j.Logger;
|
|||||||
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @version 2022-9-16
|
* This stores and calculates the colors
|
||||||
|
* the given {@link BlockState} should have based
|
||||||
|
* on the given {@link IClientLevelWrapper}.
|
||||||
|
*
|
||||||
|
* @see ColorUtil
|
||||||
*/
|
*/
|
||||||
public class ClientBlockStateCache
|
public class ClientBlockStateColorCache
|
||||||
{
|
{
|
||||||
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
|
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
|
||||||
|
|
||||||
private static final HashSet<BlockState> BLOCK_STATES_THAT_NEED_LEVEL = new HashSet<>();
|
private static final HashSet<BlockState> BLOCK_STATES_THAT_NEED_LEVEL = new HashSet<>();
|
||||||
private static final HashSet<BlockState> BROKEN_BLOCK_STATES = new HashSet<>();
|
private static final HashSet<BlockState> BROKEN_BLOCK_STATES = new HashSet<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Methods using MC's "RandomSource" object aren't thread safe <br>
|
||||||
|
* so we need to put locks around that logic. <br>
|
||||||
|
* specifically:
|
||||||
|
* <code>
|
||||||
|
* getBlockModel(this.blockState).getQuads(this.blockState, direction, RANDOM)
|
||||||
|
* </code>
|
||||||
|
*/
|
||||||
|
private static final ReentrantLock RESOLVE_LOCK = new ReentrantLock();
|
||||||
|
|
||||||
|
|
||||||
|
/** This is the order each direction on a block is processed when attempting to get the texture/color */
|
||||||
|
private static final Direction[] COLOR_RESOLUTION_DIRECTION_ORDER = { Direction.UP, Direction.NORTH, Direction.EAST, Direction.WEST, Direction.SOUTH, Direction.DOWN };
|
||||||
|
|
||||||
|
private static final int FLOWER_COLOR_SCALE = 5;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#if MC_VER < MC_1_19_2
|
#if MC_VER < MC_1_19_2
|
||||||
public static final Random random = new Random(0);
|
private static final Random RANDOM = new Random(0);
|
||||||
#else
|
#else
|
||||||
public static final RandomSource random = RandomSource.create();
|
/** Note: this object isn't thread safe and must be put in a lock */
|
||||||
|
private static final RandomSource RANDOM = RandomSource.create();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
public final IClientLevelWrapper levelWrapper;
|
private final IClientLevelWrapper levelWrapper;
|
||||||
public final BlockState blockState;
|
private final BlockState blockState;
|
||||||
public final LevelReader level;
|
private final LevelReader level;
|
||||||
public final BlockPos pos;
|
|
||||||
|
private boolean isColorResolved = false;
|
||||||
|
private int baseColor = 0;
|
||||||
|
private boolean needShade = true;
|
||||||
|
private boolean needPostTinting = false;
|
||||||
|
private int tintIndex = 0;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public ClientBlockStateCache(BlockState blockState, IClientLevelWrapper samplingLevel, DhBlockPos samplingPos)
|
//===========//
|
||||||
{
|
// constants //
|
||||||
this.blockState = blockState;
|
//===========//
|
||||||
this.levelWrapper = samplingLevel;
|
|
||||||
this.level = (LevelReader) samplingLevel.getWrappedMcObject();
|
|
||||||
this.pos = McObjectConverter.Convert(samplingPos);
|
|
||||||
this.resolveColors();
|
|
||||||
//LOGGER.info("ClientBlocKCache created for {}", blockState);
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean isColorResolved = false;
|
private static final int MIN_SRGB_BITS = 0x39000000; // 2^(-13)
|
||||||
int baseColor = 0; //TODO: Impl per-face color
|
private static final int MAX_SRGB_BITS = 0x3f7fffff; // 1.0 - f32::EPSILON
|
||||||
boolean needShade = true;
|
private static final float MIN_SRGB_BOUND = Float.intBitsToFloat(MIN_SRGB_BITS);
|
||||||
boolean needPostTinting = false;
|
private static final float MAX_SRGB_BOUND = Float.intBitsToFloat(MAX_SRGB_BITS);
|
||||||
int tintIndex = 0;
|
|
||||||
|
|
||||||
|
private static final int[] linearToSrgbTable = new int[]
|
||||||
public static final int FLOWER_COLOR_SCALE = 5;
|
|
||||||
|
|
||||||
enum ColorMode
|
|
||||||
{
|
|
||||||
Default,
|
|
||||||
Flower,
|
|
||||||
Leaves,
|
|
||||||
Chisel,
|
|
||||||
Glass;
|
|
||||||
static ColorMode getColorMode(Block b)
|
|
||||||
{
|
{
|
||||||
if (b instanceof LeavesBlock) return Leaves;
|
|
||||||
if (b instanceof FlowerBlock) return Flower;
|
|
||||||
if (b.toString().contains("glass")) return Glass;
|
|
||||||
if (b.toString().equals("Block{chiselsandbits:chiseled}")) return Chisel;
|
|
||||||
return Default;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//Way to efficiently do this was suggested by IMS from sodium. This is where those numbers and support code was lifted from.
|
|
||||||
private static final int MIN_BITS = 0x39000000; // 2^(-13)
|
|
||||||
private static final int MAX_BITS = 0x3f7fffff; // 1.0 - f32::EPSILON
|
|
||||||
private static final float MIN_BOUND = Float.intBitsToFloat(MIN_BITS);
|
|
||||||
private static final float MAX_BOUND = Float.intBitsToFloat(MAX_BITS);
|
|
||||||
|
|
||||||
private static final int[] linearToSrgbTable = new int[] {
|
|
||||||
0x0073000d, 0x007a000d, 0x0080000d, 0x0087000d, 0x008d000d, 0x0094000d, 0x009a000d, 0x00a1000d,
|
0x0073000d, 0x007a000d, 0x0080000d, 0x0087000d, 0x008d000d, 0x0094000d, 0x009a000d, 0x00a1000d,
|
||||||
0x00a7001a, 0x00b4001a, 0x00c1001a, 0x00ce001a, 0x00da001a, 0x00e7001a, 0x00f4001a, 0x0101001a,
|
0x00a7001a, 0x00b4001a, 0x00c1001a, 0x00ce001a, 0x00da001a, 0x00e7001a, 0x00f4001a, 0x0101001a,
|
||||||
0x010e0033, 0x01280033, 0x01410033, 0x015b0033, 0x01750033, 0x018f0033, 0x01a80033, 0x01c20033,
|
0x010e0033, 0x01280033, 0x01410033, 0x015b0033, 0x01750033, 0x018f0033, 0x01a80033, 0x01c20033,
|
||||||
@@ -128,81 +124,139 @@ public class ClientBlockStateCache
|
|||||||
0x31d105b0, 0x34a80555, 0x37520507, 0x39d504c5, 0x3c37048b, 0x3e7c0458, 0x40a8042a, 0x42bd0401,
|
0x31d105b0, 0x34a80555, 0x37520507, 0x39d504c5, 0x3c37048b, 0x3e7c0458, 0x40a8042a, 0x42bd0401,
|
||||||
0x44c20798, 0x488e071e, 0x4c1c06b6, 0x4f76065d, 0x52a50610, 0x55ac05cc, 0x5892058f, 0x5b590559,
|
0x44c20798, 0x488e071e, 0x4c1c06b6, 0x4f76065d, 0x52a50610, 0x55ac05cc, 0x5892058f, 0x5b590559,
|
||||||
0x5e0c0a23, 0x631c0980, 0x67db08f6, 0x6c55087f, 0x70940818, 0x74a007bd, 0x787d076c, 0x7c330723,
|
0x5e0c0a23, 0x631c0980, 0x67db08f6, 0x6c55087f, 0x70940818, 0x74a007bd, 0x787d076c, 0x7c330723,
|
||||||
};
|
};
|
||||||
|
|
||||||
private static final float[] srgbToLinearTable = new float[] {
|
private static final float[] srgbToLinearTable = new float[]
|
||||||
0.0f, 0.000303527f, 0.000607054f, 0.00091058103f, 0.001214108f, 0.001517635f, 0.0018211621f, 0.002124689f,
|
{
|
||||||
0.002428216f, 0.002731743f, 0.00303527f, 0.0033465356f, 0.003676507f, 0.004024717f, 0.004391442f,
|
0.0f, 0.000303527f, 0.000607054f, 0.00091058103f, 0.001214108f, 0.001517635f, 0.0018211621f, 0.002124689f,
|
||||||
0.0047769533f, 0.005181517f, 0.0056053917f, 0.0060488326f, 0.006512091f, 0.00699541f, 0.0074990317f,
|
0.002428216f, 0.002731743f, 0.00303527f, 0.0033465356f, 0.003676507f, 0.004024717f, 0.004391442f,
|
||||||
0.008023192f, 0.008568125f, 0.009134057f, 0.009721218f, 0.010329823f, 0.010960094f, 0.011612245f,
|
0.0047769533f, 0.005181517f, 0.0056053917f, 0.0060488326f, 0.006512091f, 0.00699541f, 0.0074990317f,
|
||||||
0.012286487f, 0.012983031f, 0.013702081f, 0.014443844f, 0.015208514f, 0.015996292f, 0.016807375f,
|
0.008023192f, 0.008568125f, 0.009134057f, 0.009721218f, 0.010329823f, 0.010960094f, 0.011612245f,
|
||||||
0.017641952f, 0.018500218f, 0.019382361f, 0.020288562f, 0.02121901f, 0.022173883f, 0.023153365f,
|
0.012286487f, 0.012983031f, 0.013702081f, 0.014443844f, 0.015208514f, 0.015996292f, 0.016807375f,
|
||||||
0.02415763f, 0.025186857f, 0.026241222f, 0.027320892f, 0.028426038f, 0.029556843f, 0.03071345f, 0.03189604f,
|
0.017641952f, 0.018500218f, 0.019382361f, 0.020288562f, 0.02121901f, 0.022173883f, 0.023153365f,
|
||||||
0.033104774f, 0.03433981f, 0.035601325f, 0.036889452f, 0.038204376f, 0.039546248f, 0.04091521f, 0.042311423f,
|
0.02415763f, 0.025186857f, 0.026241222f, 0.027320892f, 0.028426038f, 0.029556843f, 0.03071345f, 0.03189604f,
|
||||||
0.043735042f, 0.045186214f, 0.046665095f, 0.048171833f, 0.049706575f, 0.051269468f, 0.052860655f, 0.05448028f,
|
0.033104774f, 0.03433981f, 0.035601325f, 0.036889452f, 0.038204376f, 0.039546248f, 0.04091521f, 0.042311423f,
|
||||||
0.056128494f, 0.057805434f, 0.05951124f, 0.06124607f, 0.06301003f, 0.06480328f, 0.06662595f, 0.06847818f,
|
0.043735042f, 0.045186214f, 0.046665095f, 0.048171833f, 0.049706575f, 0.051269468f, 0.052860655f, 0.05448028f,
|
||||||
0.07036011f, 0.07227186f, 0.07421358f, 0.07618539f, 0.07818743f, 0.08021983f, 0.082282715f, 0.084376216f,
|
0.056128494f, 0.057805434f, 0.05951124f, 0.06124607f, 0.06301003f, 0.06480328f, 0.06662595f, 0.06847818f,
|
||||||
0.086500466f, 0.088655606f, 0.09084173f, 0.09305898f, 0.095307484f, 0.09758736f, 0.09989874f, 0.10224175f,
|
0.07036011f, 0.07227186f, 0.07421358f, 0.07618539f, 0.07818743f, 0.08021983f, 0.082282715f, 0.084376216f,
|
||||||
0.10461649f, 0.10702311f, 0.10946172f, 0.111932434f, 0.11443538f, 0.116970696f, 0.11953845f, 0.12213881f,
|
0.086500466f, 0.088655606f, 0.09084173f, 0.09305898f, 0.095307484f, 0.09758736f, 0.09989874f, 0.10224175f,
|
||||||
0.12477186f, 0.12743773f, 0.13013652f, 0.13286836f, 0.13563336f, 0.13843165f, 0.14126332f, 0.1441285f,
|
0.10461649f, 0.10702311f, 0.10946172f, 0.111932434f, 0.11443538f, 0.116970696f, 0.11953845f, 0.12213881f,
|
||||||
0.1470273f, 0.14995982f, 0.15292618f, 0.1559265f, 0.15896086f, 0.16202943f, 0.16513224f, 0.16826946f,
|
0.12477186f, 0.12743773f, 0.13013652f, 0.13286836f, 0.13563336f, 0.13843165f, 0.14126332f, 0.1441285f,
|
||||||
0.17144115f, 0.17464745f, 0.17788847f, 0.1811643f, 0.18447503f, 0.1878208f, 0.19120172f, 0.19461787f,
|
0.1470273f, 0.14995982f, 0.15292618f, 0.1559265f, 0.15896086f, 0.16202943f, 0.16513224f, 0.16826946f,
|
||||||
0.19806935f, 0.2015563f, 0.20507877f, 0.2086369f, 0.21223079f, 0.21586053f, 0.21952623f, 0.22322798f,
|
0.17144115f, 0.17464745f, 0.17788847f, 0.1811643f, 0.18447503f, 0.1878208f, 0.19120172f, 0.19461787f,
|
||||||
0.22696589f, 0.23074007f, 0.23455065f, 0.23839766f, 0.2422812f, 0.2462014f, 0.25015837f, 0.25415218f,
|
0.19806935f, 0.2015563f, 0.20507877f, 0.2086369f, 0.21223079f, 0.21586053f, 0.21952623f, 0.22322798f,
|
||||||
0.2581829f, 0.26225072f, 0.26635566f, 0.27049786f, 0.27467737f, 0.27889434f, 0.2831488f, 0.2874409f,
|
0.22696589f, 0.23074007f, 0.23455065f, 0.23839766f, 0.2422812f, 0.2462014f, 0.25015837f, 0.25415218f,
|
||||||
0.2917707f, 0.29613832f, 0.30054384f, 0.30498737f, 0.30946895f, 0.31398875f, 0.31854683f, 0.32314324f,
|
0.2581829f, 0.26225072f, 0.26635566f, 0.27049786f, 0.27467737f, 0.27889434f, 0.2831488f, 0.2874409f,
|
||||||
0.32777813f, 0.33245158f, 0.33716366f, 0.34191445f, 0.3467041f, 0.3515327f, 0.35640025f, 0.36130688f,
|
0.2917707f, 0.29613832f, 0.30054384f, 0.30498737f, 0.30946895f, 0.31398875f, 0.31854683f, 0.32314324f,
|
||||||
0.3662527f, 0.37123778f, 0.37626222f, 0.3813261f, 0.38642952f, 0.39157256f, 0.3967553f, 0.40197787f,
|
0.32777813f, 0.33245158f, 0.33716366f, 0.34191445f, 0.3467041f, 0.3515327f, 0.35640025f, 0.36130688f,
|
||||||
0.4072403f, 0.4125427f, 0.41788515f, 0.42326775f, 0.42869055f, 0.4341537f, 0.43965724f, 0.44520125f,
|
0.3662527f, 0.37123778f, 0.37626222f, 0.3813261f, 0.38642952f, 0.39157256f, 0.3967553f, 0.40197787f,
|
||||||
0.45078585f, 0.45641106f, 0.46207705f, 0.46778384f, 0.47353154f, 0.47932023f, 0.48514998f, 0.4910209f,
|
0.4072403f, 0.4125427f, 0.41788515f, 0.42326775f, 0.42869055f, 0.4341537f, 0.43965724f, 0.44520125f,
|
||||||
0.49693304f, 0.5028866f, 0.50888145f, 0.5149178f, 0.5209957f, 0.52711535f, 0.5332766f, 0.5394797f,
|
0.45078585f, 0.45641106f, 0.46207705f, 0.46778384f, 0.47353154f, 0.47932023f, 0.48514998f, 0.4910209f,
|
||||||
0.5457247f, 0.5520116f, 0.5583406f, 0.5647117f, 0.57112503f, 0.57758063f, 0.5840786f, 0.590619f, 0.597202f,
|
0.49693304f, 0.5028866f, 0.50888145f, 0.5149178f, 0.5209957f, 0.52711535f, 0.5332766f, 0.5394797f,
|
||||||
0.60382754f, 0.61049575f, 0.61720675f, 0.62396055f, 0.63075733f, 0.637597f, 0.6444799f, 0.6514058f,
|
0.5457247f, 0.5520116f, 0.5583406f, 0.5647117f, 0.57112503f, 0.57758063f, 0.5840786f, 0.590619f, 0.597202f,
|
||||||
0.65837497f, 0.66538745f, 0.67244333f, 0.6795426f, 0.68668544f, 0.69387203f, 0.70110214f, 0.70837605f,
|
0.60382754f, 0.61049575f, 0.61720675f, 0.62396055f, 0.63075733f, 0.637597f, 0.6444799f, 0.6514058f,
|
||||||
0.7156938f, 0.72305536f, 0.730461f, 0.7379107f, 0.7454045f, 0.75294244f, 0.76052475f, 0.7681514f, 0.77582246f,
|
0.65837497f, 0.66538745f, 0.67244333f, 0.6795426f, 0.68668544f, 0.69387203f, 0.70110214f, 0.70837605f,
|
||||||
0.78353804f, 0.79129815f, 0.79910296f, 0.8069525f, 0.8148468f, 0.822786f, 0.8307701f, 0.83879924f, 0.84687346f,
|
0.7156938f, 0.72305536f, 0.730461f, 0.7379107f, 0.7454045f, 0.75294244f, 0.76052475f, 0.7681514f, 0.77582246f,
|
||||||
0.8549928f, 0.8631574f, 0.87136734f, 0.8796226f, 0.8879232f, 0.89626956f, 0.90466136f, 0.913099f, 0.92158204f,
|
0.78353804f, 0.79129815f, 0.79910296f, 0.8069525f, 0.8148468f, 0.822786f, 0.8307701f, 0.83879924f, 0.84687346f,
|
||||||
0.93011117f, 0.9386859f, 0.9473069f, 0.9559735f, 0.9646866f, 0.9734455f, 0.98225087f, 0.9911022f, 1.0f
|
0.8549928f, 0.8631574f, 0.87136734f, 0.8796226f, 0.8879232f, 0.89626956f, 0.90466136f, 0.913099f, 0.92158204f,
|
||||||
};
|
0.93011117f, 0.9386859f, 0.9473069f, 0.9559735f, 0.9646866f, 0.9734455f, 0.98225087f, 0.9911022f, 1.0f
|
||||||
|
};
|
||||||
private static int linearToSrgb(float c) {
|
|
||||||
if (!(c > MIN_BOUND)) {
|
|
||||||
c = MIN_BOUND;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (c > MAX_BOUND) {
|
|
||||||
c = MAX_BOUND;
|
|
||||||
}
|
|
||||||
int inputBits = Float.floatToRawIntBits(c);
|
|
||||||
int entry = linearToSrgbTable[((inputBits - MIN_BITS) >> 20)];
|
|
||||||
|
|
||||||
int bias = (entry >>> 16) << 9;
|
|
||||||
int scale = entry & 0xffff;
|
|
||||||
int t = (inputBits >>> 12) & 0xff;
|
|
||||||
|
|
||||||
return (bias + (scale * t)) >>> 16;
|
|
||||||
}
|
|
||||||
//////////////
|
|
||||||
|
|
||||||
private static int getWidth(TextureAtlasSprite texture)
|
|
||||||
|
|
||||||
|
//=============//
|
||||||
|
// constructor //
|
||||||
|
//=============//
|
||||||
|
|
||||||
|
public ClientBlockStateColorCache(BlockState blockState, IClientLevelWrapper samplingLevel)
|
||||||
{
|
{
|
||||||
#if MC_VER < MC_1_19_4
|
this.blockState = blockState;
|
||||||
return texture.getWidth();
|
this.levelWrapper = samplingLevel;
|
||||||
#else
|
this.level = (LevelReader) samplingLevel.getWrappedMcObject();
|
||||||
return texture.contents().width();
|
this.resolveColors();
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int getHeight(TextureAtlasSprite texture)
|
|
||||||
|
|
||||||
|
//===================//
|
||||||
|
// color calculation //
|
||||||
|
//===================//
|
||||||
|
|
||||||
|
private void resolveColors()
|
||||||
{
|
{
|
||||||
#if MC_VER < MC_1_19_4
|
if (this.isColorResolved)
|
||||||
return texture.getHeight();
|
{
|
||||||
#else
|
return;
|
||||||
return texture.contents().height();
|
}
|
||||||
#endif
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// getQuads() isn't thread safe so we need to put this logic in a lock
|
||||||
|
RESOLVE_LOCK.lock();
|
||||||
|
|
||||||
|
if (this.blockState.getFluidState().isEmpty())
|
||||||
|
{
|
||||||
|
// look for the first non-empty direction
|
||||||
|
List<BakedQuad> quads = null;
|
||||||
|
for (Direction direction : COLOR_RESOLUTION_DIRECTION_ORDER)
|
||||||
|
{
|
||||||
|
quads = Minecraft.getInstance().getModelManager().getBlockModelShaper().
|
||||||
|
getBlockModel(this.blockState).getQuads(this.blockState, direction, RANDOM);
|
||||||
|
|
||||||
|
if (quads != null && !quads.isEmpty()
|
||||||
|
&& !(
|
||||||
|
this.blockState.getBlock() instanceof RotatedPillarBlock
|
||||||
|
&& direction == Direction.UP
|
||||||
|
)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (quads == null || quads.isEmpty())
|
||||||
|
{
|
||||||
|
quads = Minecraft.getInstance().getModelManager().getBlockModelShaper().
|
||||||
|
getBlockModel(this.blockState).getQuads(this.blockState, null, RANDOM);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (quads != null && !quads.isEmpty())
|
||||||
|
{
|
||||||
|
this.needPostTinting = quads.get(0).isTinted();
|
||||||
|
this.needShade = quads.get(0).isShade();
|
||||||
|
this.tintIndex = quads.get(0).getTintIndex();
|
||||||
|
this.baseColor = calculateColorFromTexture(
|
||||||
|
#if MC_VER < MC_1_17_1 quads.get(0).sprite,
|
||||||
|
#else quads.get(0).getSprite(), #endif
|
||||||
|
ColorMode.getColorMode(this.blockState.getBlock()));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Backup method.
|
||||||
|
this.needPostTinting = false;
|
||||||
|
this.needShade = false;
|
||||||
|
this.tintIndex = 0;
|
||||||
|
this.baseColor = calculateColorFromTexture(Minecraft.getInstance().getModelManager().getBlockModelShaper().getParticleIcon(this.blockState),
|
||||||
|
ColorMode.getColorMode(this.blockState.getBlock()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Liquid Block
|
||||||
|
this.needPostTinting = true;
|
||||||
|
this.needShade = false;
|
||||||
|
this.tintIndex = 0;
|
||||||
|
this.baseColor = calculateColorFromTexture(Minecraft.getInstance().getModelManager().getBlockModelShaper().getParticleIcon(this.blockState),
|
||||||
|
ColorMode.getColorMode(this.blockState.getBlock()));
|
||||||
|
}
|
||||||
|
|
||||||
|
this.isColorResolved = true;
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
RESOLVE_LOCK.unlock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//TODO: Perhaps make this not just use the first frame?
|
//TODO: Perhaps make this not just use the first frame?
|
||||||
private static int calculateColorFromTexture(TextureAtlasSprite texture, ColorMode colorMode)
|
private static int calculateColorFromTexture(TextureAtlasSprite texture, ColorMode colorMode)
|
||||||
{
|
{
|
||||||
@@ -212,13 +266,15 @@ public class ClientBlockStateCache
|
|||||||
double green = 0;
|
double green = 0;
|
||||||
double blue = 0;
|
double blue = 0;
|
||||||
int tempColor;
|
int tempColor;
|
||||||
//make Chiseled block not render. Since ColorMode is set per block, you only need to check it once
|
|
||||||
|
// don't render Chiseled blocks.
|
||||||
|
// Since ColorMode is set per block, you only need to check this once.
|
||||||
if (colorMode != ColorMode.Chisel)
|
if (colorMode != ColorMode.Chisel)
|
||||||
{
|
{
|
||||||
// textures normally use u and v instead of x and y
|
// textures normally use u and v instead of x and y
|
||||||
for (int v = 0; v < getHeight(texture); v++)
|
for (int v = 0; v < getTextureHeight(texture); v++)
|
||||||
{
|
{
|
||||||
for (int u = 0; u < getWidth(texture); u++)
|
for (int u = 0; u < getTextureWidth(texture); u++)
|
||||||
{
|
{
|
||||||
//note: Minecraft color format is: 0xAA BB GG RR
|
//note: Minecraft color format is: 0xAA BB GG RR
|
||||||
//________ DH mod color format is: 0xAA RR GG BB
|
//________ DH mod color format is: 0xAA RR GG BB
|
||||||
@@ -270,8 +326,10 @@ public class ClientBlockStateCache
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (count == 0)
|
if (count == 0)
|
||||||
|
{
|
||||||
// this block is entirely transparent
|
// this block is entirely transparent
|
||||||
tempColor = ColorUtil.rgbToInt(0, 255, 255, 255);
|
tempColor = ColorUtil.rgbToInt(0, 255, 255, 255);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// determine the average color
|
// determine the average color
|
||||||
@@ -281,6 +339,7 @@ public class ClientBlockStateCache
|
|||||||
linearToSrgb((float) (green / (double) alpha)),
|
linearToSrgb((float) (green / (double) alpha)),
|
||||||
linearToSrgb((float) (blue / (double) alpha)));
|
linearToSrgb((float) (blue / (double) alpha)));
|
||||||
}
|
}
|
||||||
|
|
||||||
//check if not missing texture
|
//check if not missing texture
|
||||||
if (tempColor == ColorUtil.rgbToInt(255, 182, 0, 182))
|
if (tempColor == ColorUtil.rgbToInt(255, 182, 0, 182))
|
||||||
{
|
{
|
||||||
@@ -289,61 +348,53 @@ public class ClientBlockStateCache
|
|||||||
}
|
}
|
||||||
return tempColor;
|
return tempColor;
|
||||||
}
|
}
|
||||||
private static final Direction[] DIRECTION_ORDER = {Direction.UP, Direction.NORTH, Direction.EAST, Direction.WEST, Direction.SOUTH, Direction.DOWN};
|
private static int getTextureWidth(TextureAtlasSprite texture)
|
||||||
|
|
||||||
private void resolveColors()
|
|
||||||
{
|
{
|
||||||
if (isColorResolved) return;
|
#if MC_VER < MC_1_19_4
|
||||||
if (blockState.getFluidState().isEmpty())
|
return texture.getWidth();
|
||||||
{
|
#else
|
||||||
List<BakedQuad> quads = null;
|
return texture.contents().width();
|
||||||
for (Direction direction : DIRECTION_ORDER)
|
#endif
|
||||||
{
|
}
|
||||||
quads = Minecraft.getInstance().getModelManager().getBlockModelShaper().
|
private static int getTextureHeight(TextureAtlasSprite texture)
|
||||||
getBlockModel(blockState).getQuads(blockState, direction, random); // TODO getQuads sometimes throws a "makeThreadingException", is there anything we can do about that? Note: this isn't a critical issue, it just prints an ugly error and the render data will need to be regenered.
|
{
|
||||||
if (quads != null && !quads.isEmpty() &&
|
#if MC_VER < MC_1_19_4
|
||||||
!(blockState.getBlock() instanceof RotatedPillarBlock && direction == Direction.UP))
|
return texture.getHeight();
|
||||||
break;
|
#else
|
||||||
} ;
|
return texture.contents().height();
|
||||||
if (quads == null || quads.isEmpty())
|
#endif
|
||||||
{
|
}
|
||||||
quads = Minecraft.getInstance().getModelManager().getBlockModelShaper().
|
/**
|
||||||
getBlockModel(blockState).getQuads(blockState, null, random);
|
* This method was suggested by IMS from the Iris/Sodium team.
|
||||||
}
|
* That's where the numbers and code are based.
|
||||||
if (quads != null && !quads.isEmpty())
|
*/
|
||||||
{
|
private static int linearToSrgb(float c)
|
||||||
needPostTinting = quads.getFirst().isTinted();
|
{
|
||||||
needShade = quads.getFirst().isShade();
|
if (!(c > MIN_SRGB_BOUND)) {
|
||||||
tintIndex = quads.getFirst().getTintIndex();
|
c = MIN_SRGB_BOUND;
|
||||||
baseColor = calculateColorFromTexture(
|
|
||||||
#if MC_VER < MC_1_17_1 quads.get(0).sprite,
|
|
||||||
#else quads.getFirst().getSprite(), #endif
|
|
||||||
ColorMode.getColorMode(blockState.getBlock()));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{ // Backup method.
|
|
||||||
needPostTinting = false;
|
|
||||||
needShade = false;
|
|
||||||
tintIndex = 0;
|
|
||||||
baseColor = calculateColorFromTexture(Minecraft.getInstance().getModelManager().getBlockModelShaper().getParticleIcon(blockState),
|
|
||||||
ColorMode.getColorMode(blockState.getBlock()));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{ // Liquid Block
|
if (c > MAX_SRGB_BOUND) {
|
||||||
needPostTinting = true;
|
c = MAX_SRGB_BOUND;
|
||||||
needShade = false;
|
|
||||||
tintIndex = 0;
|
|
||||||
baseColor = calculateColorFromTexture(Minecraft.getInstance().getModelManager().getBlockModelShaper().getParticleIcon(blockState),
|
|
||||||
ColorMode.getColorMode(blockState.getBlock()));
|
|
||||||
}
|
}
|
||||||
isColorResolved = true;
|
int inputBits = Float.floatToRawIntBits(c);
|
||||||
|
int entry = linearToSrgbTable[((inputBits - MIN_SRGB_BITS) >> 20)];
|
||||||
|
|
||||||
|
int bias = (entry >>> 16) << 9;
|
||||||
|
int scale = entry & 0xffff;
|
||||||
|
int t = (inputBits >>> 12) & 0xff;
|
||||||
|
|
||||||
|
return (bias + (scale * t)) >>> 16;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getAndResolveFaceColor(BiomeWrapper biome, DhBlockPos pos)
|
|
||||||
|
|
||||||
|
//===============//
|
||||||
|
// public getter //
|
||||||
|
//===============//
|
||||||
|
|
||||||
|
public int getColor(BiomeWrapper biome, DhBlockPos pos)
|
||||||
{
|
{
|
||||||
// FIXME: impl per-face colors
|
|
||||||
|
|
||||||
// only get the tint if the block needs to be tinted
|
// only get the tint if the block needs to be tinted
|
||||||
if (!this.needPostTinting)
|
if (!this.needPostTinting)
|
||||||
{
|
{
|
||||||
@@ -409,4 +460,30 @@ public class ClientBlockStateCache
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//================//
|
||||||
|
// helper classes //
|
||||||
|
//================//
|
||||||
|
|
||||||
|
enum ColorMode
|
||||||
|
{
|
||||||
|
Default,
|
||||||
|
Flower,
|
||||||
|
Leaves,
|
||||||
|
Chisel,
|
||||||
|
Glass;
|
||||||
|
|
||||||
|
static ColorMode getColorMode(Block block)
|
||||||
|
{
|
||||||
|
if (block instanceof LeavesBlock) return Leaves;
|
||||||
|
if (block instanceof FlowerBlock) return Flower;
|
||||||
|
if (block.toString().contains("glass")) return Glass;
|
||||||
|
if (block.toString().equals("Block{chiselsandbits:chiseled}")) return Chisel;
|
||||||
|
return Default;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
-48
@@ -1,48 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of the Distant Horizons mod
|
|
||||||
* licensed under the GNU LGPL v3 License.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2020-2023 James Seibel
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
|
||||||
* the Free Software Foundation, version 3.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.seibel.distanthorizons.common.wrappers.block.cache;
|
|
||||||
|
|
||||||
import com.seibel.distanthorizons.common.wrappers.block.BiomeWrapper;
|
|
||||||
import com.seibel.distanthorizons.common.wrappers.world.ClientLevelWrapper;
|
|
||||||
import com.seibel.distanthorizons.core.pos.DhBlockPos;
|
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
|
||||||
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
|
||||||
|
|
||||||
public class ClientBlockDetailMap
|
|
||||||
{
|
|
||||||
private final ConcurrentHashMap<BlockState, ClientBlockStateCache> blockCache = new ConcurrentHashMap<>();
|
|
||||||
//private final ConcurrentHashMap<#if MC_VER < MC_1_18_2 Biome #else Holder<Biome> #endif, Biome> biomeMap = new ConcurrentHashMap<>();
|
|
||||||
private final ClientLevelWrapper level;
|
|
||||||
public ClientBlockDetailMap(ClientLevelWrapper level) { this.level = level; }
|
|
||||||
|
|
||||||
public ClientBlockStateCache getBlockStateData(BlockState state, DhBlockPos pos)
|
|
||||||
{ //TODO: Allow a per pos unique setting
|
|
||||||
return blockCache.computeIfAbsent(state, (s) -> new ClientBlockStateCache(s, level, pos));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void clear() { blockCache.clear(); }
|
|
||||||
|
|
||||||
public int getColor(BlockState state, BiomeWrapper biome, DhBlockPos pos)
|
|
||||||
{
|
|
||||||
return getBlockStateData(state, pos).getAndResolveFaceColor(biome, pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
-43
@@ -1,43 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of the Distant Horizons mod
|
|
||||||
* licensed under the GNU LGPL v3 License.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2020-2023 James Seibel
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
|
||||||
* the Free Software Foundation, version 3.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.seibel.distanthorizons.common.wrappers.block.cache;
|
|
||||||
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
|
||||||
|
|
||||||
import com.seibel.distanthorizons.common.wrappers.world.ServerLevelWrapper;
|
|
||||||
import com.seibel.distanthorizons.core.pos.DhBlockPos;
|
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
|
||||||
|
|
||||||
|
|
||||||
public class ServerBlockDetailMap
|
|
||||||
{
|
|
||||||
private final ConcurrentHashMap<BlockState, ServerBlockStateCache> blockCache = new ConcurrentHashMap<>();
|
|
||||||
//private final ConcurrentHashMap<#if MC_VER < MC_1_18_2 Biome #else Holder<Biome> #endif, Biome> biomeMap = new ConcurrentHashMap<>();
|
|
||||||
private final ServerLevelWrapper level;
|
|
||||||
public ServerBlockDetailMap(ServerLevelWrapper level) { this.level = level; }
|
|
||||||
|
|
||||||
public ServerBlockStateCache getBlockStateData(BlockState state, DhBlockPos pos)
|
|
||||||
{ //TODO: Allow a per pos unique setting
|
|
||||||
return blockCache.computeIfAbsent(state, (s) -> new ServerBlockStateCache(s, level, new DhBlockPos(0, 0, 0)));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void clear() { blockCache.clear(); }
|
|
||||||
|
|
||||||
}
|
|
||||||
-104
@@ -1,104 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of the Distant Horizons mod
|
|
||||||
* licensed under the GNU LGPL v3 License.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2020-2023 James Seibel
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
|
||||||
* the Free Software Foundation, version 3.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.seibel.distanthorizons.common.wrappers.block.cache;
|
|
||||||
|
|
||||||
import com.seibel.distanthorizons.common.wrappers.McObjectConverter;
|
|
||||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
|
||||||
import com.seibel.distanthorizons.core.pos.DhBlockPos;
|
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper;
|
|
||||||
import net.minecraft.core.BlockPos;
|
|
||||||
import net.minecraft.core.Direction;
|
|
||||||
import net.minecraft.world.level.LevelReader;
|
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
|
||||||
import net.minecraft.world.phys.AABB;
|
|
||||||
import net.minecraft.world.phys.shapes.VoxelShape;
|
|
||||||
import org.apache.logging.log4j.Logger;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @version 2022-9-16
|
|
||||||
*/
|
|
||||||
public class ServerBlockStateCache
|
|
||||||
{
|
|
||||||
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
|
|
||||||
|
|
||||||
public final BlockState state;
|
|
||||||
public final LevelReader level;
|
|
||||||
public final BlockPos pos;
|
|
||||||
|
|
||||||
public ServerBlockStateCache(BlockState blockState, ILevelWrapper samplingLevel, DhBlockPos samplingPos)
|
|
||||||
{
|
|
||||||
state = blockState;
|
|
||||||
level = (LevelReader) samplingLevel.getWrappedMcObject();
|
|
||||||
pos = McObjectConverter.Convert(samplingPos);
|
|
||||||
resolveShapes();
|
|
||||||
//LOGGER.info("ServerBlockState created for {}", blockState);
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean noCollision = false;
|
|
||||||
boolean[] occludeFaces = null;
|
|
||||||
boolean[] fullFaces = null;
|
|
||||||
boolean isShapeResolved = false;
|
|
||||||
public void resolveShapes()
|
|
||||||
{
|
|
||||||
if (isShapeResolved) return;
|
|
||||||
if (state.getFluidState().isEmpty())
|
|
||||||
{
|
|
||||||
noCollision = state.getCollisionShape(level, pos).isEmpty();
|
|
||||||
occludeFaces = new boolean[6];
|
|
||||||
if (state.canOcclude())
|
|
||||||
{
|
|
||||||
for (Direction dir : Direction.values())
|
|
||||||
{
|
|
||||||
// Note: isEmpty() isn't quite correct... best would be a isFull() or something...
|
|
||||||
occludeFaces[McObjectConverter.Convert(dir).ordinal()]
|
|
||||||
= !state.getFaceOcclusionShape(level, pos, dir).isEmpty();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
VoxelShape voxelShape = state.getShape(level, pos);
|
|
||||||
fullFaces = new boolean[6];
|
|
||||||
if (!voxelShape.isEmpty())
|
|
||||||
{
|
|
||||||
for (Direction dir : Direction.values())
|
|
||||||
{
|
|
||||||
VoxelShape faceShape = voxelShape.getFaceShape(dir);
|
|
||||||
AABB aabb = faceShape.bounds();
|
|
||||||
boolean xFull = aabb.minX <= 0.01 && aabb.maxX >= 0.99;
|
|
||||||
boolean yFull = aabb.minY <= 0.01 && aabb.maxY >= 0.99;
|
|
||||||
boolean zFull = aabb.minZ <= 0.01 && aabb.maxZ >= 0.99;
|
|
||||||
fullFaces[McObjectConverter.Convert(dir).ordinal()] =
|
|
||||||
(xFull || dir.getAxis().equals(Direction.Axis.X))
|
|
||||||
&& (yFull || dir.getAxis().equals(Direction.Axis.Y))
|
|
||||||
&& (zFull || dir.getAxis().equals(Direction.Axis.Z));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{ // Liquid Block. Treat as full block
|
|
||||||
occludeFaces = new boolean[6];
|
|
||||||
Arrays.fill(occludeFaces, true);
|
|
||||||
fullFaces = new boolean[6];
|
|
||||||
Arrays.fill(fullFaces, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
+8
-4
@@ -83,7 +83,7 @@ public class ChunkWrapper implements IChunkWrapper
|
|||||||
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
|
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
|
||||||
|
|
||||||
/** can be used for interactions with the underlying chunk where creating new BlockPos objects could cause issues for the garbage collector. */
|
/** can be used for interactions with the underlying chunk where creating new BlockPos objects could cause issues for the garbage collector. */
|
||||||
private static final ThreadLocal<BlockPos.MutableBlockPos> MUTABLE_BLOCK_POS_REF = ThreadLocal.withInitial(BlockPos.MutableBlockPos::new);
|
private static final ThreadLocal<BlockPos.MutableBlockPos> MUTABLE_BLOCK_POS_REF = ThreadLocal.withInitial(() -> new BlockPos.MutableBlockPos());
|
||||||
|
|
||||||
|
|
||||||
private final ChunkAccess chunk;
|
private final ChunkAccess chunk;
|
||||||
@@ -345,8 +345,9 @@ public class ChunkWrapper implements IChunkWrapper
|
|||||||
#if MC_VER == MC_1_16_5 || MC_VER == MC_1_17_1
|
#if MC_VER == MC_1_16_5 || MC_VER == MC_1_17_1
|
||||||
return false; // MC's lighting engine doesn't work consistently enough to trust for 1.16 or 1.17
|
return false; // MC's lighting engine doesn't work consistently enough to trust for 1.16 or 1.17
|
||||||
#else
|
#else
|
||||||
if (this.chunk instanceof LevelChunk levelChunk)
|
if (this.chunk instanceof LevelChunk)
|
||||||
{
|
{
|
||||||
|
LevelChunk levelChunk = (LevelChunk) this.chunk;
|
||||||
if (levelChunk.getLevel() instanceof ClientLevel)
|
if (levelChunk.getLevel() instanceof ClientLevel)
|
||||||
{
|
{
|
||||||
// connected to a server
|
// connected to a server
|
||||||
@@ -473,7 +474,9 @@ public class ChunkWrapper implements IChunkWrapper
|
|||||||
});
|
});
|
||||||
#else
|
#else
|
||||||
this.chunk.findBlockLightSources((blockPos, blockState) ->
|
this.chunk.findBlockLightSources((blockPos, blockState) ->
|
||||||
this.blockLightPosList.add(new DhBlockPos(blockPos.getX(), blockPos.getY(), blockPos.getZ())));
|
{
|
||||||
|
this.blockLightPosList.add(new DhBlockPos(blockPos.getX(), blockPos.getY(), blockPos.getZ()));
|
||||||
|
});
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -504,8 +507,9 @@ public class ChunkWrapper implements IChunkWrapper
|
|||||||
/** Should be called after client light updates are triggered. */
|
/** Should be called after client light updates are triggered. */
|
||||||
private void updateIsClientLightingCorrect()
|
private void updateIsClientLightingCorrect()
|
||||||
{
|
{
|
||||||
if (this.chunk instanceof LevelChunk levelChunk && ((LevelChunk) this.chunk).getLevel() instanceof ClientLevel)
|
if (this.chunk instanceof LevelChunk && ((LevelChunk) this.chunk).getLevel() instanceof ClientLevel)
|
||||||
{
|
{
|
||||||
|
LevelChunk levelChunk = (LevelChunk) this.chunk;
|
||||||
ClientChunkCache clientChunkCache = ((ClientLevel) levelChunk.getLevel()).getChunkSource();
|
ClientChunkCache clientChunkCache = ((ClientLevel) levelChunk.getLevel()).getChunkSource();
|
||||||
this.isMcClientLightingCorrect = clientChunkCache.getChunkForLighting(this.chunk.getPos().x, this.chunk.getPos().z) != null &&
|
this.isMcClientLightingCorrect = clientChunkCache.getChunkForLighting(this.chunk.getPos().x, this.chunk.getPos().z) != null &&
|
||||||
#if MC_VER <= MC_1_17_1
|
#if MC_VER <= MC_1_17_1
|
||||||
|
|||||||
+8
-6
@@ -145,9 +145,9 @@ public class ClassicConfigGUI
|
|||||||
case 0:
|
case 0:
|
||||||
((EntryInfo) info.guiValue).error = null; break;
|
((EntryInfo) info.guiValue).error = null; break;
|
||||||
case -1:
|
case -1:
|
||||||
((EntryInfo) info.guiValue).error = new AbstractMap.SimpleEntry<>(editBox, TextOrTranslatable("§cMinimum length is " + ((ConfigEntry<?>) info).getMin())); break;
|
((EntryInfo) info.guiValue).error = new AbstractMap.SimpleEntry<>(editBox, TextOrTranslatable("§cMinimum length is " + ((ConfigEntry) info).getMin())); break;
|
||||||
case 1:
|
case 1:
|
||||||
((EntryInfo) info.guiValue).error = new AbstractMap.SimpleEntry<>(editBox, TextOrTranslatable("§cMaximum length is " + ((ConfigEntry<?>) info).getMax())); break;
|
((EntryInfo) info.guiValue).error = new AbstractMap.SimpleEntry<>(editBox, TextOrTranslatable("§cMaximum length is " + ((ConfigEntry) info).getMax())); break;
|
||||||
case 2:
|
case 2:
|
||||||
((EntryInfo) info.guiValue).error = new AbstractMap.SimpleEntry<>(editBox, TextOrTranslatable("§cValue is invalid")); break;
|
((EntryInfo) info.guiValue).error = new AbstractMap.SimpleEntry<>(editBox, TextOrTranslatable("§cValue is invalid")); break;
|
||||||
}
|
}
|
||||||
@@ -235,7 +235,7 @@ public class ClassicConfigGUI
|
|||||||
ConfigBase.INSTANCE.configFileINSTANCE.saveToFile();
|
ConfigBase.INSTANCE.configFileINSTANCE.saveToFile();
|
||||||
Objects.requireNonNull(this.minecraft).setScreen(this.parent);
|
Objects.requireNonNull(this.minecraft).setScreen(this.parent);
|
||||||
|
|
||||||
CONFIG_CORE_INTERFACE.onScreenChangeListenerList.forEach(Runnable::run);
|
CONFIG_CORE_INTERFACE.onScreenChangeListenerList.forEach((listener) -> listener.run());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -319,7 +319,7 @@ public class ClassicConfigGUI
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
CONFIG_CORE_INTERFACE.onScreenChangeListenerList.forEach(Runnable::run);
|
CONFIG_CORE_INTERFACE.onScreenChangeListenerList.forEach((listener) -> listener.run());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -332,7 +332,7 @@ public class ClassicConfigGUI
|
|||||||
if (ConfigEntry.class.isAssignableFrom(info.getClass()))
|
if (ConfigEntry.class.isAssignableFrom(info.getClass()))
|
||||||
{
|
{
|
||||||
Button.OnPress btnAction = button -> {
|
Button.OnPress btnAction = button -> {
|
||||||
((ConfigEntry) info).uiSetWithoutSaving(((ConfigEntry<?>) info).getDefaultValue());
|
((ConfigEntry) info).uiSetWithoutSaving(((ConfigEntry) info).getDefaultValue());
|
||||||
((EntryInfo) info.guiValue).index = 0;
|
((EntryInfo) info.guiValue).index = 0;
|
||||||
this.reload = true;
|
this.reload = true;
|
||||||
Objects.requireNonNull(minecraft).setScreen(this);
|
Objects.requireNonNull(minecraft).setScreen(this);
|
||||||
@@ -376,7 +376,9 @@ public class ClassicConfigGUI
|
|||||||
}
|
}
|
||||||
if (ConfigUIButton.class.isAssignableFrom(info.getClass()))
|
if (ConfigUIButton.class.isAssignableFrom(info.getClass()))
|
||||||
{
|
{
|
||||||
Button widget = MakeBtn(name, this.width / 2 - 100, this.height - 28, 100 * 2, 20, (button -> ((ConfigUIButton) info).runAction()));
|
Button widget = MakeBtn(name, this.width / 2 - 100, this.height - 28, 100 * 2, 20, (button -> {
|
||||||
|
((ConfigUIButton) info).runAction();
|
||||||
|
}));
|
||||||
this.list.addButton(widget, null, null, null);
|
this.list.addButton(widget, null, null, null);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
+10
-9
@@ -25,18 +25,19 @@ public class GetConfigScreen
|
|||||||
// This shouldn't be here, but I need a way to test it after Minecraft inits its assets
|
// This shouldn't be here, but I need a way to test it after Minecraft inits its assets
|
||||||
//System.out.println(ConfigBase.INSTANCE.generateLang(false, true));
|
//System.out.println(ConfigBase.INSTANCE.generateLang(false, true));
|
||||||
|
|
||||||
return switch (useScreen)
|
switch (useScreen)
|
||||||
{
|
{
|
||||||
case Classic -> ClassicConfigGUI.getScreen(ConfigBase.INSTANCE, parent, "client");
|
case Classic:
|
||||||
case OpenGL ->
|
return ClassicConfigGUI.getScreen(ConfigBase.INSTANCE, parent, "client");
|
||||||
{
|
case OpenGL:
|
||||||
MinecraftScreen.getScreen(parent, new OpenGLConfigScreen(), ModInfo.ID + ".title");
|
MinecraftScreen.getScreen(parent, new OpenGLConfigScreen(), ModInfo.ID + ".title");
|
||||||
yield null;
|
return null;
|
||||||
}
|
|
||||||
// case JavaFX -> MinecraftScreen.getScreen(parent, new JavaScreenHandlerScreen(new JavaScreenHandlerScreen.ExampleScreen()), ModInfo.ID + ".title");
|
// case JavaFX -> MinecraftScreen.getScreen(parent, new JavaScreenHandlerScreen(new JavaScreenHandlerScreen.ExampleScreen()), ModInfo.ID + ".title");
|
||||||
case JavaFX -> MinecraftScreen.getScreen(parent, new JavaScreenHandlerScreen(new ConfigScreen()), ModInfo.ID + ".title");
|
case JavaFX:
|
||||||
default -> throw new IllegalArgumentException("No config screen implementation defined for [" + useScreen + "].");
|
return MinecraftScreen.getScreen(parent, new JavaScreenHandlerScreen(new ConfigScreen()), ModInfo.ID + ".title");
|
||||||
};
|
default:
|
||||||
|
throw new IllegalArgumentException("No config screen implementation defined for ["+useScreen+"].");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
+3
-1
@@ -134,7 +134,9 @@ public class ChangelogScreen extends DhScreen
|
|||||||
|
|
||||||
|
|
||||||
this.addBtn( // Close
|
this.addBtn( // Close
|
||||||
MakeBtn(Translatable(ModInfo.ID + ".general.back"), 5, this.height - 25, 100, 20, (btn) -> this.onClose())
|
MakeBtn(Translatable(ModInfo.ID + ".general.back"), 5, this.height - 25, 100, 20, (btn) -> {
|
||||||
|
this.onClose();
|
||||||
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+3
-1
@@ -135,7 +135,9 @@ public class UpdateModScreen extends DhScreen
|
|||||||
})
|
})
|
||||||
);
|
);
|
||||||
this.addBtn( // Later (not now)
|
this.addBtn( // Later (not now)
|
||||||
MakeBtn(Translatable(ModInfo.ID + ".updater.later"), this.width / 2 + 2, this.height / 2 + 70, 100, 20, (btn) -> this.onClose())
|
MakeBtn(Translatable(ModInfo.ID + ".updater.later"), this.width / 2 + 2, this.height / 2 + 70, 100, 20, (btn) -> {
|
||||||
|
this.onClose();
|
||||||
|
})
|
||||||
);
|
);
|
||||||
this.addBtn( // Never
|
this.addBtn( // Never
|
||||||
MakeBtn(Translatable(ModInfo.ID + ".updater.never"), this.width / 2 - 102, this.height / 2 + 70, 100, 20, (btn) -> {
|
MakeBtn(Translatable(ModInfo.ID + ".updater.never"), this.width / 2 - 102, this.height / 2 + 70, 100, 20, (btn) -> {
|
||||||
|
|||||||
+15
-7
@@ -127,12 +127,20 @@ public class MinecraftClientWrapper implements IMinecraftClientWrapper, IMinecra
|
|||||||
}
|
}
|
||||||
|
|
||||||
case ENABLED:
|
case ENABLED:
|
||||||
return switch (lodDirection) {
|
switch (lodDirection)
|
||||||
case DOWN -> 0.5F;
|
{
|
||||||
default -> 1.0F;
|
case DOWN:
|
||||||
case NORTH, SOUTH -> 0.8F;
|
return 0.5F;
|
||||||
case WEST, EAST -> 0.6F;
|
default:
|
||||||
};
|
case UP:
|
||||||
|
return 1.0F;
|
||||||
|
case NORTH:
|
||||||
|
case SOUTH:
|
||||||
|
return 0.8F;
|
||||||
|
case WEST:
|
||||||
|
case EAST:
|
||||||
|
return 0.6F;
|
||||||
|
}
|
||||||
|
|
||||||
case DISABLED:
|
case DISABLED:
|
||||||
return 1.0F;
|
return 1.0F;
|
||||||
@@ -242,7 +250,7 @@ public class MinecraftClientWrapper implements IMinecraftClientWrapper, IMinecra
|
|||||||
@Override
|
@Override
|
||||||
public ArrayList<ILevelWrapper> getAllServerWorlds()
|
public ArrayList<ILevelWrapper> getAllServerWorlds()
|
||||||
{
|
{
|
||||||
ArrayList<ILevelWrapper> worlds = new ArrayList<>();
|
ArrayList<ILevelWrapper> worlds = new ArrayList<ILevelWrapper>();
|
||||||
|
|
||||||
Iterable<ServerLevel> serverWorlds = MINECRAFT.getSingleplayerServer().getAllLevels();
|
Iterable<ServerLevel> serverWorlds = MINECRAFT.getSingleplayerServer().getAllLevels();
|
||||||
for (ServerLevel world : serverWorlds)
|
for (ServerLevel world : serverWorlds)
|
||||||
|
|||||||
-116
@@ -120,14 +120,6 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper
|
|||||||
return new Vec3f(camera.getLookVector().x(), camera.getLookVector().y(), camera.getLookVector().z());
|
return new Vec3f(camera.getLookVector().x(), camera.getLookVector().y(), camera.getLookVector().z());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public DhBlockPos getCameraBlockPosition()
|
|
||||||
{
|
|
||||||
Camera camera = MC.gameRenderer.getMainCamera();
|
|
||||||
BlockPos blockPos = camera.getBlockPosition();
|
|
||||||
return new DhBlockPos(blockPos.getX(), blockPos.getY(), blockPos.getZ());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
/** Unless you really need to know if the player is blind, use {@link MinecraftRenderWrapper#isFogStateSpecial()}/{@link IMinecraftRenderWrapper#isFogStateSpecial()} instead */
|
/** Unless you really need to know if the player is blind, use {@link MinecraftRenderWrapper#isFogStateSpecial()}/{@link IMinecraftRenderWrapper#isFogStateSpecial()} instead */
|
||||||
public boolean playerHasBlindingEffect()
|
public boolean playerHasBlindingEffect()
|
||||||
@@ -148,43 +140,6 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper
|
|||||||
return new Vec3d(projectedView.x, projectedView.y, projectedView.z);
|
return new Vec3d(projectedView.x, projectedView.y, projectedView.z);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Mat4f getWorldViewMatrix()
|
|
||||||
{
|
|
||||||
Camera camera = MC.gameRenderer.getMainCamera();
|
|
||||||
Vector3f cameraVec3 = new Vector3f(
|
|
||||||
(float)camera.getPosition().x,
|
|
||||||
(float)camera.getPosition().y,
|
|
||||||
(float)camera.getPosition().z);
|
|
||||||
cameraVec3 = cameraVec3.negate();
|
|
||||||
|
|
||||||
Matrix4f matWorldView = new Matrix4f()
|
|
||||||
.rotateX((float)Math.toRadians(camera.getXRot()))
|
|
||||||
.rotateY((float)Math.toRadians(camera.getYRot() + 180f))
|
|
||||||
.translate(cameraVec3);
|
|
||||||
return new Mat4f(matWorldView);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Mat4f getDefaultProjectionMatrix(float partialTicks)
|
|
||||||
{
|
|
||||||
#if MC_VER < MC_1_17_1
|
|
||||||
return McObjectConverter.Convert(Minecraft.getInstance().gameRenderer.getProjectionMatrix(Minecraft.getInstance().gameRenderer.getMainCamera(), partialTicks, true));
|
|
||||||
#else
|
|
||||||
return McObjectConverter.Convert(MC.gameRenderer.getProjectionMatrix(MC.gameRenderer.getFov(MC.gameRenderer.getMainCamera(), partialTicks, true)));
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public double getGamma()
|
|
||||||
{
|
|
||||||
#if MC_VER < MC_1_19_2
|
|
||||||
return MC.options.gamma;
|
|
||||||
#else
|
|
||||||
return MC.options.gamma().get();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Color getFogColor(float partialTicks)
|
public Color getFogColor(float partialTicks)
|
||||||
{
|
{
|
||||||
@@ -314,77 +269,6 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper
|
|||||||
return getRenderTarget().viewHeight;
|
return getRenderTarget().viewHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* This method returns the ChunkPos of all chunks that Minecraft
|
|
||||||
* is going to render this frame. <br><br>
|
|
||||||
* <p>
|
|
||||||
*/
|
|
||||||
|
|
||||||
public boolean usingBackupGetVanillaRenderedChunks = false;
|
|
||||||
@Override
|
|
||||||
public HashSet<DhChunkPos> getVanillaRenderedChunks()
|
|
||||||
{
|
|
||||||
ISodiumAccessor sodium = ModAccessorInjector.INSTANCE.get(ISodiumAccessor.class);
|
|
||||||
if (sodium != null)
|
|
||||||
{
|
|
||||||
return sodium.getNormalRenderedChunks();
|
|
||||||
}
|
|
||||||
IOptifineAccessor optifine = ModAccessorInjector.INSTANCE.get(IOptifineAccessor.class);
|
|
||||||
if (optifine != null)
|
|
||||||
{
|
|
||||||
HashSet<DhChunkPos> pos = optifine.getNormalRenderedChunks();
|
|
||||||
if (pos == null)
|
|
||||||
pos = getMaximumRenderedChunks();
|
|
||||||
return pos;
|
|
||||||
}
|
|
||||||
if (!usingBackupGetVanillaRenderedChunks)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
#if MC_VER < MC_1_20_2
|
|
||||||
LevelRenderer levelRenderer = MC.levelRenderer;
|
|
||||||
Collection<LevelRenderer.RenderChunkInfo> chunks =
|
|
||||||
#if MC_VER < MC_1_18_2 levelRenderer.renderChunks;
|
|
||||||
#else levelRenderer.renderChunkStorage.get().renderChunks; #endif
|
|
||||||
|
|
||||||
return (chunks.stream().map((chunk) -> {
|
|
||||||
AABB chunkBoundingBox =
|
|
||||||
#if MC_VER < MC_1_18_2 chunk.chunk.bb;
|
|
||||||
#else chunk.chunk.getBoundingBox(); #endif
|
|
||||||
return new DhChunkPos(Math.floorDiv((int) chunkBoundingBox.minX, 16),
|
|
||||||
Math.floorDiv((int) chunkBoundingBox.minZ, 16));
|
|
||||||
}).collect(Collectors.toCollection(HashSet::new)));
|
|
||||||
#else
|
|
||||||
LevelRenderer levelRenderer = MC.levelRenderer;
|
|
||||||
Collection<SectionRenderDispatcher.RenderSection> chunks = levelRenderer.visibleSections;
|
|
||||||
|
|
||||||
return (chunks.stream().map((chunk) -> {
|
|
||||||
AABB chunkBoundingBox = chunk.getBoundingBox();
|
|
||||||
return new DhChunkPos(Math.floorDiv((int) chunkBoundingBox.minX, 16),
|
|
||||||
Math.floorDiv((int) chunkBoundingBox.minZ, 16));
|
|
||||||
}).collect(Collectors.toCollection(HashSet::new)));
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
catch (LinkageError e)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
MinecraftClientWrapper.INSTANCE.sendChatMessage(
|
|
||||||
"\u00A7e\u00A7l\u00A7uWARNING: Distant Horizons: getVanillaRenderedChunks method failed."
|
|
||||||
+ " Using Backup Method.");
|
|
||||||
MinecraftClientWrapper.INSTANCE.sendChatMessage(
|
|
||||||
"\u00A7eOverdraw prevention will be worse than normal.");
|
|
||||||
}
|
|
||||||
catch (Exception e2)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
LOGGER.error("getVanillaRenderedChunks Error: ", e);
|
|
||||||
usingBackupGetVanillaRenderedChunks = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return getMaximumRenderedChunks();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ILightMapWrapper getLightmapWrapper(ILevelWrapper level) { return this.lightmapByDimensionType.get(level.getDimensionType()); }
|
public ILightMapWrapper getLightmapWrapper(ILevelWrapper level) { return this.lightmapByDimensionType.get(level.getDimensionType()); }
|
||||||
|
|
||||||
|
|||||||
+16
-7
@@ -5,14 +5,15 @@ import com.seibel.distanthorizons.api.interfaces.render.IDhApiCustomRenderRegist
|
|||||||
import com.seibel.distanthorizons.common.wrappers.McObjectConverter;
|
import com.seibel.distanthorizons.common.wrappers.McObjectConverter;
|
||||||
import com.seibel.distanthorizons.common.wrappers.block.BiomeWrapper;
|
import com.seibel.distanthorizons.common.wrappers.block.BiomeWrapper;
|
||||||
import com.seibel.distanthorizons.common.wrappers.block.BlockStateWrapper;
|
import com.seibel.distanthorizons.common.wrappers.block.BlockStateWrapper;
|
||||||
import com.seibel.distanthorizons.common.wrappers.block.cache.ClientBlockDetailMap;
|
import com.seibel.distanthorizons.common.wrappers.block.ClientBlockStateColorCache;
|
||||||
import com.seibel.distanthorizons.common.wrappers.chunk.ChunkWrapper;
|
import com.seibel.distanthorizons.common.wrappers.chunk.ChunkWrapper;
|
||||||
import com.seibel.distanthorizons.common.wrappers.minecraft.MinecraftClientWrapper;
|
import com.seibel.distanthorizons.core.api.internal.ClientApi;
|
||||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||||
import com.seibel.distanthorizons.core.level.*;
|
import com.seibel.distanthorizons.core.level.*;
|
||||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||||
import com.seibel.distanthorizons.core.pos.DhBlockPos;
|
import com.seibel.distanthorizons.core.pos.DhBlockPos;
|
||||||
import com.seibel.distanthorizons.core.pos.DhChunkPos;
|
import com.seibel.distanthorizons.core.pos.DhChunkPos;
|
||||||
|
import com.seibel.distanthorizons.core.util.ColorUtil;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.block.IBlockStateWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.block.IBlockStateWrapper;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.chunk.IChunkWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.chunk.IChunkWrapper;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IBiomeWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IBiomeWrapper;
|
||||||
@@ -22,6 +23,7 @@ import com.seibel.distanthorizons.core.wrapperInterfaces.world.IServerLevelWrapp
|
|||||||
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.server.level.ServerLevel;
|
import net.minecraft.server.level.ServerLevel;
|
||||||
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
import net.minecraft.world.level.chunk.ChunkAccess;
|
import net.minecraft.world.level.chunk.ChunkAccess;
|
||||||
import net.minecraft.world.level.chunk.ChunkSource;
|
import net.minecraft.world.level.chunk.ChunkSource;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
@@ -46,7 +48,7 @@ public class ClientLevelWrapper implements IClientLevelWrapper
|
|||||||
private static final Minecraft MINECRAFT = Minecraft.getInstance();
|
private static final Minecraft MINECRAFT = Minecraft.getInstance();
|
||||||
|
|
||||||
private final ClientLevel level;
|
private final ClientLevel level;
|
||||||
private final ClientBlockDetailMap blockMap = new ClientBlockDetailMap(this);
|
private final ConcurrentHashMap<BlockState, ClientBlockStateColorCache> blockCache = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
private BlockStateWrapper dirtBlockWrapper;
|
private BlockStateWrapper dirtBlockWrapper;
|
||||||
private BiomeWrapper plainsBiomeWrapper;
|
private BiomeWrapper plainsBiomeWrapper;
|
||||||
@@ -111,7 +113,7 @@ public class ClientLevelWrapper implements IClientLevelWrapper
|
|||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
LOGGER.error("Failed to get server side wrapper for client level: " + level);
|
LOGGER.error("Failed to get server side wrapper for client level: " + this.level);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -123,9 +125,13 @@ public class ClientLevelWrapper implements IClientLevelWrapper
|
|||||||
//====================//
|
//====================//
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int computeBaseColor(DhBlockPos pos, IBiomeWrapper biome, IBlockStateWrapper blockState)
|
public int getBlockColor(DhBlockPos pos, IBiomeWrapper biome, IBlockStateWrapper blockWrapper)
|
||||||
{
|
{
|
||||||
return this.blockMap.getColor(((BlockStateWrapper) blockState).blockState, (BiomeWrapper) biome, pos);
|
ClientBlockStateColorCache blockColorCache = this.blockCache.computeIfAbsent(
|
||||||
|
((BlockStateWrapper) blockWrapper).blockState,
|
||||||
|
(block) -> new ClientBlockStateColorCache(block, this));
|
||||||
|
|
||||||
|
return blockColorCache.getColor((BiomeWrapper) biome, pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -145,9 +151,12 @@ public class ClientLevelWrapper implements IClientLevelWrapper
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.blockMap.getColor(this.dirtBlockWrapper.blockState, BiomeWrapper.EMPTY_WRAPPER, DhBlockPos.ZERO);
|
return this.getBlockColor(DhBlockPos.ZERO,BiomeWrapper.EMPTY_WRAPPER, this.dirtBlockWrapper);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clearBlockColorCache() { this.blockCache.clear(); }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IBiomeWrapper getPlainsBiomeWrapper()
|
public IBiomeWrapper getPlainsBiomeWrapper()
|
||||||
{
|
{
|
||||||
|
|||||||
-3
@@ -27,9 +27,7 @@ import com.seibel.distanthorizons.api.interfaces.render.IDhApiCustomRenderRegist
|
|||||||
import com.seibel.distanthorizons.common.wrappers.McObjectConverter;
|
import com.seibel.distanthorizons.common.wrappers.McObjectConverter;
|
||||||
import com.seibel.distanthorizons.common.wrappers.block.BiomeWrapper;
|
import com.seibel.distanthorizons.common.wrappers.block.BiomeWrapper;
|
||||||
import com.seibel.distanthorizons.common.wrappers.block.BlockStateWrapper;
|
import com.seibel.distanthorizons.common.wrappers.block.BlockStateWrapper;
|
||||||
import com.seibel.distanthorizons.common.wrappers.block.cache.ServerBlockDetailMap;
|
|
||||||
import com.seibel.distanthorizons.common.wrappers.chunk.ChunkWrapper;
|
import com.seibel.distanthorizons.common.wrappers.chunk.ChunkWrapper;
|
||||||
import com.seibel.distanthorizons.common.wrappers.minecraft.MinecraftClientWrapper;
|
|
||||||
import com.seibel.distanthorizons.core.level.IDhLevel;
|
import com.seibel.distanthorizons.core.level.IDhLevel;
|
||||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||||
import com.seibel.distanthorizons.core.pos.DhBlockPos;
|
import com.seibel.distanthorizons.core.pos.DhBlockPos;
|
||||||
@@ -37,7 +35,6 @@ import com.seibel.distanthorizons.core.pos.DhChunkPos;
|
|||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.block.IBlockStateWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.block.IBlockStateWrapper;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.chunk.IChunkWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.chunk.IChunkWrapper;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IBiomeWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IBiomeWrapper;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
|
|
||||||
|
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IServerLevelWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IServerLevelWrapper;
|
||||||
import net.minecraft.server.level.ServerLevel;
|
import net.minecraft.server.level.ServerLevel;
|
||||||
|
|||||||
+223
-158
@@ -147,7 +147,7 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
|
|||||||
if (index == -1) continue;
|
if (index == -1) continue;
|
||||||
times.get(index).add(e.timeNs);
|
times.get(index).add(e.timeNs);
|
||||||
}
|
}
|
||||||
times.getFirst().add(event.getTotalTimeNs());
|
times.get(0).add(event.getTotalTimeNs());
|
||||||
}
|
}
|
||||||
|
|
||||||
public String toString()
|
public String toString()
|
||||||
@@ -224,8 +224,8 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
|
|||||||
// constructors //
|
// constructors //
|
||||||
//==============//
|
//==============//
|
||||||
|
|
||||||
public static ImmutableMap<EDhApiWorldGenerationStep, Integer> BorderNeeded;
|
public static final ImmutableMap<EDhApiWorldGenerationStep, Integer> WORLD_GEN_CHUNK_BORDER_NEEDED_BY_GEN_STEP;
|
||||||
public static int MaxBorderNeeded;
|
public static final int MAX_WORLD_GEN_CHUNK_BORDER_NEEDED;
|
||||||
|
|
||||||
static
|
static
|
||||||
{
|
{
|
||||||
@@ -253,8 +253,13 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
|
|||||||
builder.put(EDhApiWorldGenerationStep.LIQUID_CARVERS, 0);
|
builder.put(EDhApiWorldGenerationStep.LIQUID_CARVERS, 0);
|
||||||
builder.put(EDhApiWorldGenerationStep.FEATURES, 0);
|
builder.put(EDhApiWorldGenerationStep.FEATURES, 0);
|
||||||
builder.put(EDhApiWorldGenerationStep.LIGHT, 0);
|
builder.put(EDhApiWorldGenerationStep.LIGHT, 0);
|
||||||
BorderNeeded = builder.build();
|
WORLD_GEN_CHUNK_BORDER_NEEDED_BY_GEN_STEP = builder.build();
|
||||||
MaxBorderNeeded = BorderNeeded.values().stream().mapToInt(Integer::intValue).max().getAsInt();
|
|
||||||
|
// TODO this is a test to see if the additional boarder is actually necessary or not.
|
||||||
|
// If world generators end up having infinite loops or other unexplained issues,
|
||||||
|
// this should be set back to the commented out logic below
|
||||||
|
MAX_WORLD_GEN_CHUNK_BORDER_NEEDED = 0;
|
||||||
|
//MAX_WORLD_GEN_CHUNK_BORDER_NEEDED = WORLD_GEN_CHUNK_BORDER_NEEDED_BY_GEN_STEP.values().stream().mapToInt(Integer::intValue).max().getAsInt();
|
||||||
}
|
}
|
||||||
|
|
||||||
public BatchGenerationEnvironment(IDhServerLevel serverlevel)
|
public BatchGenerationEnvironment(IDhServerLevel serverlevel)
|
||||||
@@ -383,171 +388,177 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
|
|||||||
{
|
{
|
||||||
EVENT_LOGGER.debug("Lod Generate Event: " + genEvent.minPos);
|
EVENT_LOGGER.debug("Lod Generate Event: " + genEvent.minPos);
|
||||||
|
|
||||||
ArrayGridList<ChunkWrapper> chunkWrapperList;
|
// Minecraft's generation events expect odd chunk width areas (3x3, 7x7, or 11x11),
|
||||||
DhLitWorldGenRegion region;
|
// but DH submits square generation events (4x4).
|
||||||
DummyLightEngine dummyLightEngine;
|
// We handle this later, although that handling would need to change if the gen size ever changed.
|
||||||
LightGetterAdaptor adaptor;
|
LodUtil.assertTrue(genEvent.size % 2 == 0, "Generation events are expected to be an evan number of chunks wide.");
|
||||||
|
|
||||||
int borderSize = MaxBorderNeeded;
|
|
||||||
int refSize = genEvent.size + borderSize * 2;
|
|
||||||
|
int borderSize = MAX_WORLD_GEN_CHUNK_BORDER_NEEDED;
|
||||||
|
// genEvent.size - 1 converts the even width size to an odd number for MC compatability
|
||||||
|
int refSize = (genEvent.size - 1) + (borderSize * 2);
|
||||||
int refPosX = genEvent.minPos.x - borderSize;
|
int refPosX = genEvent.minPos.x - borderSize;
|
||||||
int refPosZ = genEvent.minPos.z - borderSize;
|
int refPosZ = genEvent.minPos.z - borderSize;
|
||||||
|
|
||||||
try
|
LightGetterAdaptor lightGetterAdaptor = new LightGetterAdaptor(this.params.level);
|
||||||
|
DummyLightEngine dummyLightEngine = new DummyLightEngine(lightGetterAdaptor);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//====================================//
|
||||||
|
// offset and generate odd width area //
|
||||||
|
//====================================//
|
||||||
|
|
||||||
|
// reused data between each offset
|
||||||
|
HashMap<DhChunkPos, ChunkLightStorage> chunkSkyLightingByDhPos = new HashMap<>();
|
||||||
|
HashMap<DhChunkPos, ChunkLightStorage> chunkBlockLightingByDhPos = new HashMap<>();
|
||||||
|
HashMap<DhChunkPos, ChunkAccess> generatedChunkByDhPos = new HashMap<>();
|
||||||
|
HashMap<DhChunkPos, ChunkWrapper> chunkWrappersByDhPos = new HashMap<>();
|
||||||
|
|
||||||
|
// offset 1 chunk in both X and Z direction so we can generate an even number of chunks wide
|
||||||
|
// while still submitting odd numbers to MC's internal generators
|
||||||
|
for (int xOffset = 0; xOffset < 2; xOffset++)
|
||||||
{
|
{
|
||||||
ArrayGridList<ChunkAccess> totalChunks;
|
// final is so the offset can be used in lambdas
|
||||||
|
final int xOffsetFinal = xOffset;
|
||||||
adaptor = new LightGetterAdaptor(this.params.level);
|
for (int zOffset = 0; zOffset < 2; zOffset++)
|
||||||
dummyLightEngine = new DummyLightEngine(adaptor);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//=============================//
|
|
||||||
// try getting existing chunks //
|
|
||||||
//=============================//
|
|
||||||
|
|
||||||
HashMap<DhChunkPos, ChunkLightStorage> chunkSkyLightingByDhPos = new HashMap<>();
|
|
||||||
HashMap<DhChunkPos, ChunkLightStorage> chunkBlockLightingByDhPos = new HashMap<>();
|
|
||||||
IEmptyChunkGeneratorFunc emptyChunkGeneratorFunc = (int x, int z) ->
|
|
||||||
{
|
{
|
||||||
ChunkPos chunkPos = new ChunkPos(x, z);
|
final int zOffsetFinal = zOffset;
|
||||||
DhChunkPos dhChunkPos = new DhChunkPos(x, z);
|
|
||||||
ChunkAccess newChunk = null;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
// get the chunk
|
|
||||||
CompoundTag chunkData = this.getChunkNbtData(chunkPos);
|
|
||||||
newChunk = this.loadOrMakeChunk(chunkPos, chunkData);
|
|
||||||
|
|
||||||
if (Config.Client.Advanced.LodBuilding.pullLightingForPregeneratedChunks.get())
|
|
||||||
{
|
|
||||||
// attempt to get chunk lighting
|
|
||||||
ChunkLoader.CombinedChunkLightStorage combinedLights = ChunkLoader.readLight(newChunk, chunkData);
|
|
||||||
if (combinedLights != null)
|
|
||||||
{
|
|
||||||
chunkSkyLightingByDhPos.put(dhChunkPos, combinedLights.skyLightStorage);
|
|
||||||
chunkBlockLightingByDhPos.put(dhChunkPos, combinedLights.blockLightStorage);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (RuntimeException loadChunkError)
|
|
||||||
{
|
|
||||||
// Continue...
|
|
||||||
}
|
|
||||||
|
|
||||||
if (newChunk == null)
|
|
||||||
|
|
||||||
|
//================//
|
||||||
|
// variable setup //
|
||||||
|
//================//
|
||||||
|
|
||||||
|
int radius = refSize / 2;
|
||||||
|
int centerX = refPosX + radius + xOffset;
|
||||||
|
int centerZ = refPosZ + radius + zOffset;
|
||||||
|
|
||||||
|
// get/create the list of chunks we're going to generate
|
||||||
|
ArrayGridList<ChunkAccess> regionChunks = new ArrayGridList<>(
|
||||||
|
refSize,
|
||||||
|
(x, z) -> this.generateEmptyChunk(
|
||||||
|
x + refPosX + xOffsetFinal,
|
||||||
|
z + refPosZ + zOffsetFinal,
|
||||||
|
chunkSkyLightingByDhPos, chunkBlockLightingByDhPos, generatedChunkByDhPos));
|
||||||
|
ChunkAccess centerChunk = regionChunks.stream().filter(chunk -> chunk.getPos().x == centerX && chunk.getPos().z == centerZ).findFirst().get();
|
||||||
|
|
||||||
|
genEvent.refreshTimeout();
|
||||||
|
DhLitWorldGenRegion region = new DhLitWorldGenRegion(
|
||||||
|
centerX, centerZ,
|
||||||
|
centerChunk,
|
||||||
|
this.params.level, dummyLightEngine, regionChunks,
|
||||||
|
ChunkStatus.STRUCTURE_STARTS, radius,
|
||||||
|
// this method shouldn't be necessary since we're passing in a pre-populated
|
||||||
|
// list of chunks, but just in case
|
||||||
|
(x, z) -> this.generateEmptyChunk(x, z, chunkSkyLightingByDhPos, chunkBlockLightingByDhPos, generatedChunkByDhPos)
|
||||||
|
);
|
||||||
|
lightGetterAdaptor.setRegion(region);
|
||||||
|
genEvent.threadedParam.makeStructFeat(region, this.params);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//=========================//
|
||||||
|
// create chunk wrappers //
|
||||||
|
// and get existing chunks //
|
||||||
|
//=========================//
|
||||||
|
|
||||||
|
ArrayGridList<ChunkWrapper> chunkWrapperList = new ArrayGridList<>(regionChunks.gridSize);
|
||||||
|
regionChunks.forEachPos((relX, relZ) ->
|
||||||
{
|
{
|
||||||
newChunk = new ProtoChunk(chunkPos, UpgradeData.EMPTY
|
// ArrayGridList's use relative positions and don't have a center position
|
||||||
#if MC_VER >= MC_1_17_1 , this.params.level #endif
|
// so we need to use the offsetFinal to select the correct position
|
||||||
#if MC_VER >= MC_1_18_2 , this.params.biomes, null #endif
|
DhChunkPos chunkPos = new DhChunkPos(relX + xOffsetFinal, relZ + zOffsetFinal);
|
||||||
);
|
ChunkAccess chunk = regionChunks.get(relX, relZ);
|
||||||
}
|
|
||||||
return newChunk;
|
|
||||||
};
|
|
||||||
totalChunks = new ArrayGridList<>(refSize, (x, z) -> emptyChunkGeneratorFunc.generate(x + refPosX, z + refPosZ));
|
|
||||||
|
|
||||||
int radius = refSize / 2;
|
|
||||||
int centerX = refPosX + radius;
|
|
||||||
int centerZ = refPosZ + radius;
|
|
||||||
|
|
||||||
ChunkAccess centerChunk = totalChunks.stream().filter(chunk -> chunk.getPos().x == centerX && chunk.getPos().z == centerZ).findFirst().get();
|
|
||||||
|
|
||||||
genEvent.refreshTimeout();
|
|
||||||
region = new DhLitWorldGenRegion(
|
|
||||||
centerX, centerZ,
|
|
||||||
centerChunk,
|
|
||||||
this.params.level, dummyLightEngine, totalChunks,
|
|
||||||
ChunkStatus.STRUCTURE_STARTS, radius, emptyChunkGeneratorFunc);
|
|
||||||
adaptor.setRegion(region);
|
|
||||||
genEvent.threadedParam.makeStructFeat(region, this.params);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//=======================//
|
|
||||||
// create chunk wrappers //
|
|
||||||
//=======================//
|
|
||||||
|
|
||||||
chunkWrapperList = new ArrayGridList<>(totalChunks.gridSize);
|
|
||||||
totalChunks.forEachPos((x, z) ->
|
|
||||||
{
|
|
||||||
ChunkAccess chunk = totalChunks.get(x, z);
|
|
||||||
if (chunk != null)
|
|
||||||
{
|
|
||||||
// wrap the chunk
|
|
||||||
ChunkWrapper chunkWrapper = new ChunkWrapper(chunk, region, this.serverlevel.getLevelWrapper());
|
|
||||||
chunkWrapperList.set(x, z, chunkWrapper);
|
|
||||||
|
|
||||||
// try setting the wrapper's lighting
|
if (chunkWrappersByDhPos.containsKey(chunkPos))
|
||||||
if (chunkBlockLightingByDhPos.containsKey(chunkWrapper.getChunkPos()))
|
|
||||||
{
|
{
|
||||||
chunkWrapper.setBlockLightStorage(chunkBlockLightingByDhPos.get(chunkWrapper.getChunkPos()));
|
chunkWrapperList.set(relX, relZ, chunkWrappersByDhPos.get(chunkPos));
|
||||||
chunkWrapper.setSkyLightStorage(chunkSkyLightingByDhPos.get(chunkWrapper.getChunkPos()));
|
|
||||||
chunkWrapper.setUseDhLighting(true);
|
|
||||||
chunkWrapper.setIsDhLightCorrect(true);
|
|
||||||
}
|
}
|
||||||
}
|
else if (chunk != null)
|
||||||
});
|
{
|
||||||
|
// wrap the chunk
|
||||||
|
ChunkWrapper chunkWrapper = new ChunkWrapper(chunk, region, this.serverlevel.getLevelWrapper());
|
||||||
|
chunkWrapperList.set(relX, relZ, chunkWrapper);
|
||||||
//=================//
|
|
||||||
// generate chunks //
|
// try setting the wrapper's lighting
|
||||||
//=================//
|
if (chunkBlockLightingByDhPos.containsKey(chunkWrapper.getChunkPos()))
|
||||||
|
{
|
||||||
this.generateDirect(genEvent, chunkWrapperList, borderSize, genEvent.targetGenerationStep, region);
|
chunkWrapper.setBlockLightStorage(chunkBlockLightingByDhPos.get(chunkWrapper.getChunkPos()));
|
||||||
genEvent.timer.nextEvent("cleanup");
|
chunkWrapper.setSkyLightStorage(chunkSkyLightingByDhPos.get(chunkWrapper.getChunkPos()));
|
||||||
}
|
chunkWrapper.setUseDhLighting(true);
|
||||||
catch (StepStructureStart.StructStartCorruptedException f)
|
chunkWrapper.setIsDhLightCorrect(true);
|
||||||
{
|
}
|
||||||
genEvent.threadedParam.markAsInvalid();
|
|
||||||
throw (RuntimeException) f.getCause();
|
chunkWrappersByDhPos.put(chunkPos, chunkWrapper);
|
||||||
|
}
|
||||||
|
else //if (chunk == null)
|
||||||
|
{
|
||||||
|
LodUtil.assertNotReach("Programmer Error: No chunk found in grid list, position offset is likely wrong.");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//=================//
|
||||||
|
// generate chunks //
|
||||||
|
//=================//
|
||||||
|
|
||||||
|
this.generateDirect(genEvent, chunkWrapperList, borderSize, genEvent.targetGenerationStep, region);
|
||||||
|
|
||||||
|
genEvent.timer.nextEvent("cleanup");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ArrayGridList<ChunkWrapper> finalGenChunks = GetCutoutFrom(chunkWrapperList, borderSize);
|
|
||||||
for (int offsetY = 0; offsetY < finalGenChunks.gridSize; offsetY++)
|
|
||||||
|
//=========================//
|
||||||
|
// submit generated chunks //
|
||||||
|
//=========================//
|
||||||
|
|
||||||
|
for (DhChunkPos dhChunkPos : chunkWrappersByDhPos.keySet())
|
||||||
{
|
{
|
||||||
for (int offsetX = 0; offsetX < finalGenChunks.gridSize; offsetX++)
|
ChunkWrapper wrappedChunk = chunkWrappersByDhPos.get(dhChunkPos);
|
||||||
|
ChunkAccess target = wrappedChunk.getChunk();
|
||||||
|
if (target instanceof LevelChunk)
|
||||||
{
|
{
|
||||||
ChunkWrapper wrappedChunk = finalGenChunks.get(offsetX, offsetY);
|
#if MC_VER == MC_1_16_5 || MC_VER == MC_1_17_1
|
||||||
ChunkAccess target = wrappedChunk.getChunk();
|
((LevelChunk) target).setLoaded(true);
|
||||||
if (target instanceof LevelChunk)
|
#else
|
||||||
{
|
((LevelChunk) target).loaded = true;
|
||||||
#if MC_VER == MC_1_16_5 || MC_VER == MC_1_17_1
|
|
||||||
((LevelChunk) target).setLoaded(true);
|
|
||||||
#else
|
|
||||||
((LevelChunk) target).loaded = true;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!wrappedChunk.isLightCorrect())
|
|
||||||
{
|
|
||||||
throw new RuntimeException("The generated chunk somehow has isLightCorrect() returning false");
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean isFull = ChunkWrapper.getStatus(target) == ChunkStatus.FULL || target instanceof LevelChunk;
|
|
||||||
#if MC_VER >= MC_1_18_2
|
|
||||||
boolean isPartial = target.isOldNoiseGeneration();
|
|
||||||
#endif
|
#endif
|
||||||
if (isFull)
|
}
|
||||||
{
|
|
||||||
LOAD_LOGGER.info("Detected full existing chunk at {}", target.getPos());
|
if (!wrappedChunk.isLightCorrect())
|
||||||
genEvent.resultConsumer.accept(wrappedChunk);
|
{
|
||||||
}
|
throw new RuntimeException("The generated chunk somehow has isLightCorrect() returning false");
|
||||||
#if MC_VER >= MC_1_18_2
|
}
|
||||||
else if (isPartial)
|
|
||||||
{
|
boolean isFull = ChunkWrapper.getStatus(target) == ChunkStatus.FULL || target instanceof LevelChunk;
|
||||||
LOAD_LOGGER.info("Detected old existing chunk at {}", target.getPos());
|
#if MC_VER >= MC_1_18_2
|
||||||
genEvent.resultConsumer.accept(wrappedChunk);
|
boolean isPartial = target.isOldNoiseGeneration();
|
||||||
}
|
#endif
|
||||||
#endif
|
if (isFull)
|
||||||
else if (ChunkWrapper.getStatus(target) == ChunkStatus.EMPTY)
|
{
|
||||||
{
|
LOAD_LOGGER.debug("Detected full existing chunk at {}", target.getPos());
|
||||||
genEvent.resultConsumer.accept(wrappedChunk);
|
genEvent.resultConsumer.accept(wrappedChunk);
|
||||||
}
|
}
|
||||||
else
|
#if MC_VER >= MC_1_18_2
|
||||||
{
|
else if (isPartial)
|
||||||
genEvent.resultConsumer.accept(wrappedChunk);
|
{
|
||||||
}
|
LOAD_LOGGER.debug("Detected old existing chunk at {}", target.getPos());
|
||||||
|
genEvent.resultConsumer.accept(wrappedChunk);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
else if (ChunkWrapper.getStatus(target) == ChunkStatus.EMPTY)
|
||||||
|
{
|
||||||
|
genEvent.resultConsumer.accept(wrappedChunk);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
genEvent.resultConsumer.accept(wrappedChunk);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -556,9 +567,58 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
|
|||||||
if (PREF_LOGGER.canMaybeLog())
|
if (PREF_LOGGER.canMaybeLog())
|
||||||
{
|
{
|
||||||
genEvent.threadedParam.perf.recordEvent(genEvent.timer);
|
genEvent.threadedParam.perf.recordEvent(genEvent.timer);
|
||||||
PREF_LOGGER.infoInc("{}", genEvent.timer);
|
PREF_LOGGER.debugInc("{}", genEvent.timer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
private ChunkAccess generateEmptyChunk(
|
||||||
|
int x, int z,
|
||||||
|
HashMap<DhChunkPos, ChunkLightStorage> chunkSkyLightingByDhPos,
|
||||||
|
HashMap<DhChunkPos, ChunkLightStorage> chunkBlockLightingByDhPos,
|
||||||
|
HashMap<DhChunkPos, ChunkAccess> generatedChunkByDhPos)
|
||||||
|
{
|
||||||
|
ChunkPos chunkPos = new ChunkPos(x, z);
|
||||||
|
DhChunkPos dhChunkPos = new DhChunkPos(x, z);
|
||||||
|
|
||||||
|
if (generatedChunkByDhPos.containsKey(dhChunkPos))
|
||||||
|
{
|
||||||
|
return generatedChunkByDhPos.get(dhChunkPos);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ChunkAccess newChunk = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// get the chunk
|
||||||
|
CompoundTag chunkData = this.getChunkNbtData(chunkPos);
|
||||||
|
newChunk = this.loadOrMakeChunk(chunkPos, chunkData);
|
||||||
|
|
||||||
|
if (Config.Client.Advanced.LodBuilding.pullLightingForPregeneratedChunks.get())
|
||||||
|
{
|
||||||
|
// attempt to get chunk lighting
|
||||||
|
ChunkLoader.CombinedChunkLightStorage combinedLights = ChunkLoader.readLight(newChunk, chunkData);
|
||||||
|
if (combinedLights != null)
|
||||||
|
{
|
||||||
|
chunkSkyLightingByDhPos.put(dhChunkPos, combinedLights.skyLightStorage);
|
||||||
|
chunkBlockLightingByDhPos.put(dhChunkPos, combinedLights.blockLightStorage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (RuntimeException loadChunkError)
|
||||||
|
{
|
||||||
|
// Continue...
|
||||||
|
}
|
||||||
|
|
||||||
|
if (newChunk == null)
|
||||||
|
{
|
||||||
|
newChunk = new ProtoChunk(chunkPos, UpgradeData.EMPTY
|
||||||
|
#if MC_VER >= MC_1_17_1 , this.params.level #endif
|
||||||
|
#if MC_VER >= MC_1_18_2 , this.params.biomes, null #endif
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
generatedChunkByDhPos.put(dhChunkPos, newChunk);
|
||||||
|
return newChunk;
|
||||||
|
}
|
||||||
private CompoundTag getChunkNbtData(ChunkPos chunkPos)
|
private CompoundTag getChunkNbtData(ChunkPos chunkPos)
|
||||||
{
|
{
|
||||||
ServerLevel level = this.params.level;
|
ServerLevel level = this.params.level;
|
||||||
@@ -609,7 +669,7 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
LOAD_LOGGER.info("DistantHorizons: Loading chunk [" + chunkPos + "] from disk.");
|
LOAD_LOGGER.debug("DistantHorizons: Loading chunk [" + chunkPos + "] from disk.");
|
||||||
return ChunkLoader.read(level, chunkPos, chunkData);
|
return ChunkLoader.read(level, chunkPos, chunkData);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
@@ -639,6 +699,9 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public void generateDirect(
|
public void generateDirect(
|
||||||
GenerationEvent genEvent, ArrayGridList<ChunkWrapper> chunksToGenerate, int border,
|
GenerationEvent genEvent, ArrayGridList<ChunkWrapper> chunksToGenerate, int border,
|
||||||
EDhApiWorldGenerationStep step, DhLitWorldGenRegion region) throws InterruptedException
|
EDhApiWorldGenerationStep step, DhLitWorldGenRegion region) throws InterruptedException
|
||||||
@@ -653,8 +716,9 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
|
|||||||
chunksToGenerate.forEach((chunkWrapper) ->
|
chunksToGenerate.forEach((chunkWrapper) ->
|
||||||
{
|
{
|
||||||
ChunkAccess chunk = chunkWrapper.getChunk();
|
ChunkAccess chunk = chunkWrapper.getChunk();
|
||||||
if (chunk instanceof ProtoChunk protoChunk)
|
if (chunk instanceof ProtoChunk)
|
||||||
{
|
{
|
||||||
|
ProtoChunk protoChunk = ((ProtoChunk) chunk);
|
||||||
|
|
||||||
protoChunk.setLightEngine(region.getLightEngine());
|
protoChunk.setLightEngine(region.getLightEngine());
|
||||||
}
|
}
|
||||||
@@ -769,7 +833,8 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
private static <T> ArrayGridList<T> GetCutoutFrom(ArrayGridList<T> total, int border) { return new ArrayGridList<>(total, border, total.gridSize - border); }
|
private static <T> ArrayGridList<T> GetCutoutFrom(ArrayGridList<T> total, int border) { return new ArrayGridList<>(total, border, total.gridSize - border); }
|
||||||
private static <T> ArrayGridList<T> GetCutoutFrom(ArrayGridList<T> total, EDhApiWorldGenerationStep step) { return GetCutoutFrom(total, MaxBorderNeeded - BorderNeeded.get(step)); }
|
//private static <T> ArrayGridList<T> GetCutoutFrom(ArrayGridList<T> total, EDhApiWorldGenerationStep step) { return GetCutoutFrom(total, MaxBorderNeeded - WORLD_GEN_CHUNK_BORDER_NEEDED_BY_GEN_STEP.get(step)); }
|
||||||
|
private static <T> ArrayGridList<T> GetCutoutFrom(ArrayGridList<T> total, EDhApiWorldGenerationStep step) { return GetCutoutFrom(total, 0); }
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
+6
-22
@@ -43,6 +43,7 @@ public final class GenerationEvent
|
|||||||
public final int id;
|
public final int id;
|
||||||
public final ThreadedParameters threadedParam;
|
public final ThreadedParameters threadedParam;
|
||||||
public final DhChunkPos minPos;
|
public final DhChunkPos minPos;
|
||||||
|
/** the number of chunks wide this event is */
|
||||||
public final int size;
|
public final int size;
|
||||||
public final EDhApiWorldGenerationStep targetGenerationStep;
|
public final EDhApiWorldGenerationStep targetGenerationStep;
|
||||||
public EventTimer timer = null;
|
public EventTimer timer = null;
|
||||||
@@ -73,10 +74,10 @@ public final class GenerationEvent
|
|||||||
EDhApiWorldGenerationStep target, Consumer<IChunkWrapper> resultConsumer,
|
EDhApiWorldGenerationStep target, Consumer<IChunkWrapper> resultConsumer,
|
||||||
ExecutorService worldGeneratorThreadPool)
|
ExecutorService worldGeneratorThreadPool)
|
||||||
{
|
{
|
||||||
if (size % 2 == 0)
|
//if (size % 2 == 0)
|
||||||
{
|
//{
|
||||||
size += 1; // size must be odd for vanilla world gen regions to work
|
// size += 1; // size must be odd for vanilla world gen regions to work
|
||||||
}
|
//}
|
||||||
|
|
||||||
|
|
||||||
GenerationEvent generationEvent = new GenerationEvent(minPos, size, genEnvironment, target, resultConsumer);
|
GenerationEvent generationEvent = new GenerationEvent(minPos, size, genEnvironment, target, resultConsumer);
|
||||||
@@ -93,9 +94,7 @@ public final class GenerationEvent
|
|||||||
//LOGGER.info("generating [{}]", event.minPos);
|
//LOGGER.info("generating [{}]", event.minPos);
|
||||||
genEnvironment.generateLodFromList(generationEvent);
|
genEnvironment.generateLodFromList(generationEvent);
|
||||||
}
|
}
|
||||||
catch (InterruptedException ignored)
|
catch (InterruptedException ignored) { }
|
||||||
{
|
|
||||||
}
|
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
BatchGenerationEnvironment.isDistantGeneratorThread.remove();
|
BatchGenerationEnvironment.isDistantGeneratorThread.remove();
|
||||||
@@ -126,21 +125,6 @@ public final class GenerationEvent
|
|||||||
return this.future.isCancelled();
|
return this.future.isCancelled();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean tooClose(int minX, int minZ, int width)
|
|
||||||
{
|
|
||||||
int aMinX = this.minPos.x;
|
|
||||||
int aMinZ = this.minPos.z;
|
|
||||||
int aSize = this.size;
|
|
||||||
// Account for required empty chunks in the border
|
|
||||||
aSize += 1;
|
|
||||||
width += 1;
|
|
||||||
// Do a AABB to AABB intersection test
|
|
||||||
return (aMinX + aSize >= minX &&
|
|
||||||
aMinX <= minX + width &&
|
|
||||||
aMinZ + aSize >= minZ &&
|
|
||||||
aMinZ <= minZ + width);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void refreshTimeout()
|
public void refreshTimeout()
|
||||||
{
|
{
|
||||||
this.timeoutTime = System.nanoTime();
|
this.timeoutTime = System.nanoTime();
|
||||||
|
|||||||
+7
-6
@@ -294,7 +294,7 @@ public class ChunkLoader
|
|||||||
#else
|
#else
|
||||||
.getOrThrow((message) -> (RuntimeException) LOGGER.errorAndThrow(message, null))
|
.getOrThrow((message) -> (RuntimeException) LOGGER.errorAndThrow(message, null))
|
||||||
#endif
|
#endif
|
||||||
: new PalettedContainer<>(Block.BLOCK_STATE_REGISTRY, Blocks.AIR.defaultBlockState(), PalettedContainer.Strategy.SECTION_STATES);
|
: new PalettedContainer<BlockState>(Block.BLOCK_STATE_REGISTRY, Blocks.AIR.defaultBlockState(), PalettedContainer.Strategy.SECTION_STATES);
|
||||||
|
|
||||||
#if MC_VER < MC_1_18_2
|
#if MC_VER < MC_1_18_2
|
||||||
biomeContainer = tagSection.contains("biomes", 10)
|
biomeContainer = tagSection.contains("biomes", 10)
|
||||||
@@ -309,7 +309,7 @@ public class ChunkLoader
|
|||||||
#else
|
#else
|
||||||
.getOrThrow((message) -> (RuntimeException) LOGGER.errorAndThrow(message, null))
|
.getOrThrow((message) -> (RuntimeException) LOGGER.errorAndThrow(message, null))
|
||||||
#endif
|
#endif
|
||||||
: new PalettedContainer<>(biomes.asHolderIdMap(), biomes.getHolderOrThrow(Biomes.PLAINS), PalettedContainer.Strategy.SECTION_BIOMES);
|
: new PalettedContainer<Holder<Biome>>(biomes.asHolderIdMap(), biomes.getHolderOrThrow(Biomes.PLAINS), PalettedContainer.Strategy.SECTION_BIOMES);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if MC_VER < MC_1_20_1
|
#if MC_VER < MC_1_20_1
|
||||||
@@ -434,7 +434,7 @@ public class ChunkLoader
|
|||||||
for (int sectionIndex = 0; sectionIndex < chunkSectionListTag.size(); sectionIndex++)
|
for (int sectionIndex = 0; sectionIndex < chunkSectionListTag.size(); sectionIndex++)
|
||||||
{
|
{
|
||||||
Tag chunkSectionTag = chunkSectionListTag.get(sectionIndex);
|
Tag chunkSectionTag = chunkSectionListTag.get(sectionIndex);
|
||||||
if (!(chunkSectionTag instanceof CompoundTag chunkSectionCompoundTag))
|
if (!(chunkSectionTag instanceof CompoundTag))
|
||||||
{
|
{
|
||||||
if (!lightingSectionErrorLogged)
|
if (!lightingSectionErrorLogged)
|
||||||
{
|
{
|
||||||
@@ -443,9 +443,10 @@ public class ChunkLoader
|
|||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
CompoundTag chunkSectionCompoundTag = (CompoundTag) chunkSectionTag;
|
||||||
|
|
||||||
// if null all lights = 0
|
|
||||||
|
// if null all lights = 0
|
||||||
byte[] blockLightNibbleArray = chunkSectionCompoundTag.getByteArray("BlockLight");
|
byte[] blockLightNibbleArray = chunkSectionCompoundTag.getByteArray("BlockLight");
|
||||||
byte[] skyLightNibbleArray = chunkSectionCompoundTag.getByteArray("SkyLight");
|
byte[] skyLightNibbleArray = chunkSectionCompoundTag.getByteArray("SkyLight");
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -84,7 +84,7 @@ public class DhLitWorldGenRegion extends WorldGenRegion
|
|||||||
|
|
||||||
private final ChunkPos firstPos;
|
private final ChunkPos firstPos;
|
||||||
private final List<ChunkAccess> cache;
|
private final List<ChunkAccess> cache;
|
||||||
private final Long2ObjectOpenHashMap<ChunkAccess> chunkMap = new Long2ObjectOpenHashMap<>();
|
private final Long2ObjectOpenHashMap<ChunkAccess> chunkMap = new Long2ObjectOpenHashMap<ChunkAccess>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Present to reduce the chance that we accidentally break underlying MC code that isn't thread safe,
|
* Present to reduce the chance that we accidentally break underlying MC code that isn't thread safe,
|
||||||
@@ -142,7 +142,7 @@ public class DhLitWorldGenRegion extends WorldGenRegion
|
|||||||
centerChunk);
|
centerChunk);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
this.firstPos = chunkList.getFirst().getPos();
|
this.firstPos = chunkList.get(0).getPos();
|
||||||
this.generator = generator;
|
this.generator = generator;
|
||||||
this.lightEngine = lightEngine;
|
this.lightEngine = lightEngine;
|
||||||
this.writeRadius = writeRadius;
|
this.writeRadius = writeRadius;
|
||||||
|
|||||||
+3
-1
@@ -231,9 +231,11 @@ public class WorldGenStructFeatManager extends #if MC_VER < MC_1_19_2 StructureF
|
|||||||
Map<Structure, LongSet> map = chunk.getAllReferences();
|
Map<Structure, LongSet> map = chunk.getAllReferences();
|
||||||
|
|
||||||
ImmutableList.Builder<StructureStart> builder = ImmutableList.builder();
|
ImmutableList.Builder<StructureStart> builder = ImmutableList.builder();
|
||||||
|
Iterator<Map.Entry<Structure, LongSet>> var5 = map.entrySet().iterator();
|
||||||
|
|
||||||
for (Map.Entry<Structure, LongSet> entry : map.entrySet())
|
while (var5.hasNext())
|
||||||
{
|
{
|
||||||
|
Map.Entry<Structure, LongSet> entry = var5.next();
|
||||||
Structure configuredStructureFeature = entry.getKey();
|
Structure configuredStructureFeature = entry.getKey();
|
||||||
if (predicate.test(configuredStructureFeature))
|
if (predicate.test(configuredStructureFeature))
|
||||||
{
|
{
|
||||||
|
|||||||
+1
-1
@@ -54,7 +54,7 @@ public final class StepStructureReference
|
|||||||
List<ChunkWrapper> chunkWrappers)
|
List<ChunkWrapper> chunkWrappers)
|
||||||
{
|
{
|
||||||
|
|
||||||
ArrayList<ChunkAccess> chunksToDo = new ArrayList<>();
|
ArrayList<ChunkAccess> chunksToDo = new ArrayList<ChunkAccess>();
|
||||||
|
|
||||||
for (ChunkWrapper chunkWrapper : chunkWrappers)
|
for (ChunkWrapper chunkWrapper : chunkWrappers)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"required": true,
|
||||||
|
"minVersion": "0.8",
|
||||||
|
"package": "com.seibel.distanthorizons.common.mixins",
|
||||||
|
"mixins": [
|
||||||
|
],
|
||||||
|
"client": [
|
||||||
|
"client.MixinDebugScreenOverlay",
|
||||||
|
"client.MixinFogRenderer",
|
||||||
|
"client.MixinGameRenderer",
|
||||||
|
"client.MixinLightTexture"
|
||||||
|
],
|
||||||
|
"server": []
|
||||||
|
}
|
||||||
+1
-1
Submodule coreSubProjects updated: f767215ff0...377d0fbe12
+2
-2
@@ -23,8 +23,8 @@ loom {
|
|||||||
}
|
}
|
||||||
|
|
||||||
remapJar {
|
remapJar {
|
||||||
inputFile = shadeDowngradedApi.archiveFile
|
inputFile = shadowJar.archiveFile
|
||||||
dependsOn shadeDowngradedApi
|
dependsOn shadowJar
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -106,7 +106,7 @@ public class FabricClientProxy implements AbstractModInitializer.IEventProxy
|
|||||||
// tick events //
|
// tick events //
|
||||||
//=============//
|
//=============//
|
||||||
|
|
||||||
ClientTickEvents.START_CLIENT_TICK.register((client) -> ClientApi.INSTANCE.clientTickEvent());
|
ClientTickEvents.START_CLIENT_TICK.register((client) -> { ClientApi.INSTANCE.clientTickEvent(); });
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -124,7 +124,7 @@ public class FabricMain extends AbstractModInitializer implements ClientModIniti
|
|||||||
|
|
||||||
#if MC_VER >= MC_1_20_1
|
#if MC_VER >= MC_1_20_1
|
||||||
if (SingletonInjector.INSTANCE.get(IModChecker.class).isModLoaded("sodium"))
|
if (SingletonInjector.INSTANCE.get(IModChecker.class).isModLoaded("sodium"))
|
||||||
ModAccessorInjector.INSTANCE.get(ISodiumAccessor.class).setFogOcclusion(false); // FIXME: This is a tmp fix for sodium 0.5.0, and 0.5.1. This is fixed in sodium 0.5.2
|
ModAccessorInjector.INSTANCE.get(ISodiumAccessor.class).setFogOcclusion(false);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (ConfigBase.INSTANCE == null)
|
if (ConfigBase.INSTANCE == null)
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
package com.seibel.distanthorizons.fabric;
|
package com.seibel.distanthorizons.fabric;
|
||||||
|
|
||||||
|
import com.seibel.distanthorizons.api.methods.events.DhApiEventRegister;
|
||||||
|
import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiLevelLoadEvent;
|
||||||
import com.seibel.distanthorizons.common.AbstractModInitializer;
|
import com.seibel.distanthorizons.common.AbstractModInitializer;
|
||||||
import com.seibel.distanthorizons.common.wrappers.chunk.ChunkWrapper;
|
import com.seibel.distanthorizons.common.wrappers.chunk.ChunkWrapper;
|
||||||
import com.seibel.distanthorizons.common.wrappers.misc.ServerPlayerWrapper;
|
import com.seibel.distanthorizons.common.wrappers.misc.ServerPlayerWrapper;
|
||||||
@@ -10,6 +12,7 @@ import com.seibel.distanthorizons.core.api.internal.ServerApi;
|
|||||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper;
|
||||||
|
import com.seibel.distanthorizons.fabric.testing.TestWorldGenBindingEvent;
|
||||||
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerChunkEvents;
|
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerChunkEvents;
|
||||||
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents;
|
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents;
|
||||||
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents;
|
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents;
|
||||||
@@ -75,6 +78,14 @@ public class FabricServerProxy implements AbstractModInitializer.IEventProxy
|
|||||||
// ServerTickEvent
|
// ServerTickEvent
|
||||||
ServerTickEvents.END_SERVER_TICK.register((server) -> SERVER_API.serverTickEvent());
|
ServerTickEvents.END_SERVER_TICK.register((server) -> SERVER_API.serverTickEvent());
|
||||||
|
|
||||||
|
|
||||||
|
// can be enabled to test world gen overrides without having to build a separate API project
|
||||||
|
if (false)
|
||||||
|
{
|
||||||
|
DhApiEventRegister.on(DhApiLevelLoadEvent.class, new TestWorldGenBindingEvent());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// ServerWorldLoadEvent
|
// ServerWorldLoadEvent
|
||||||
//TODO: Check if both of these use the correct timed events. (i.e. is it 'ed' or 'ing' one?)
|
//TODO: Check if both of these use the correct timed events. (i.e. is it 'ed' or 'ing' one?)
|
||||||
ServerLifecycleEvents.SERVER_STARTING.register((server) ->
|
ServerLifecycleEvents.SERVER_STARTING.register((server) ->
|
||||||
|
|||||||
+1
-1
@@ -98,7 +98,7 @@ public class MixinMinecraft
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
versionId = GitlabGetter.INSTANCE.projectPipelines.getFirst().get("sha");
|
versionId = GitlabGetter.INSTANCE.projectPipelines.get(0).get("sha");
|
||||||
}
|
}
|
||||||
|
|
||||||
Minecraft.getInstance().setScreen(new UpdateModScreen(
|
Minecraft.getInstance().setScreen(new UpdateModScreen(
|
||||||
|
|||||||
+3
-3
@@ -104,14 +104,14 @@ public class MixinOptionsScreen extends Screen
|
|||||||
|
|
||||||
// add the button to the correct location in the UI
|
// add the button to the correct location in the UI
|
||||||
// TODO is there a better way to do this instead of using access transformers to inject into the exact UI elements?
|
// TODO is there a better way to do this instead of using access transformers to inject into the exact UI elements?
|
||||||
LinearLayout layout = (LinearLayout) this.layout.headerFrame.children.getFirst().child;
|
LinearLayout layout = (LinearLayout) this.layout.headerFrame.children.get(0).child;
|
||||||
|
|
||||||
// determine how wide the other option buttons are so we can put our botton to the left of them all
|
// determine how wide the other option buttons are so we can put our botton to the left of them all
|
||||||
AtomicInteger width = new AtomicInteger(0);
|
AtomicInteger width = new AtomicInteger(0);
|
||||||
layout.visitChildren(x -> width.addAndGet(x.getWidth()));
|
layout.visitChildren(x -> { width.addAndGet(x.getWidth()); });
|
||||||
width.addAndGet(-10); // padding between the DH button and the FOV slider
|
width.addAndGet(-10); // padding between the DH button and the FOV slider
|
||||||
|
|
||||||
layout.wrapped.addChild(this.getOptionsButton(), 1, 2, (settings) -> settings.paddingLeft(width.get() * -1));
|
layout.wrapped.addChild(this.getOptionsButton(), 1, 2, (settings) -> { settings.paddingLeft(width.get() * -1); });
|
||||||
layout.arrangeElements();
|
layout.arrangeElements();
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+28
@@ -0,0 +1,28 @@
|
|||||||
|
package com.seibel.distanthorizons.fabric.testing;
|
||||||
|
|
||||||
|
import com.mojang.logging.LogUtils;
|
||||||
|
import com.seibel.distanthorizons.api.DhApi;
|
||||||
|
import com.seibel.distanthorizons.api.interfaces.override.worldGenerator.IDhApiWorldGenerator;
|
||||||
|
import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiLevelLoadEvent;
|
||||||
|
import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiEventParam;
|
||||||
|
import com.seibel.distanthorizons.fabric.FabricServerProxy;
|
||||||
|
import net.minecraft.server.level.ServerLevel;
|
||||||
|
|
||||||
|
public class TestWorldGenBindingEvent extends DhApiLevelLoadEvent
|
||||||
|
{
|
||||||
|
private static final org.slf4j.Logger LOGGER = LogUtils.getLogger();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLevelLoad(DhApiEventParam<DhApiLevelLoadEvent.EventParam> event)
|
||||||
|
{
|
||||||
|
LOGGER.info("DH Level: ["+event.value.levelWrapper.getDimensionType()+"] loaded.");
|
||||||
|
|
||||||
|
// Note: whenever you use a wrapper method on a new Minecraft version it is recommended that you
|
||||||
|
// call wrapper.getClass() to determine which object the API will return before you try casting it.
|
||||||
|
ServerLevel level = (ServerLevel) event.value.levelWrapper.getWrappedMcObject();
|
||||||
|
|
||||||
|
// override the core DH world generator for this level
|
||||||
|
IDhApiWorldGenerator exampleWorldGen = new TestWorldGenerator(level);
|
||||||
|
DhApi.worldGenOverrides.registerWorldGeneratorOverride(event.value.levelWrapper, exampleWorldGen);
|
||||||
|
}
|
||||||
|
}
|
||||||
+82
@@ -0,0 +1,82 @@
|
|||||||
|
package com.seibel.distanthorizons.fabric.testing;
|
||||||
|
|
||||||
|
import com.seibel.distanthorizons.api.DhApi;
|
||||||
|
import com.seibel.distanthorizons.api.enums.worldGeneration.EDhApiDistantGeneratorMode;
|
||||||
|
import com.seibel.distanthorizons.api.enums.worldGeneration.EDhApiWorldGeneratorReturnType;
|
||||||
|
import com.seibel.distanthorizons.api.interfaces.block.IDhApiBiomeWrapper;
|
||||||
|
import com.seibel.distanthorizons.api.interfaces.block.IDhApiBlockStateWrapper;
|
||||||
|
import com.seibel.distanthorizons.api.interfaces.override.worldGenerator.AbstractDhApiChunkWorldGenerator;
|
||||||
|
import com.seibel.distanthorizons.api.interfaces.world.IDhApiLevelWrapper;
|
||||||
|
import com.seibel.distanthorizons.api.objects.data.DhApiChunk;
|
||||||
|
import com.seibel.distanthorizons.api.objects.data.DhApiTerrainDataPoint;
|
||||||
|
import com.seibel.distanthorizons.common.wrappers.world.ServerLevelWrapper;
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.server.level.ServerLevel;
|
||||||
|
import net.minecraft.world.level.chunk.ChunkAccess;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
public class TestWorldGenerator extends AbstractDhApiChunkWorldGenerator
|
||||||
|
{
|
||||||
|
private final ServerLevel level;
|
||||||
|
private final IDhApiLevelWrapper levelWrapper;
|
||||||
|
|
||||||
|
public TestWorldGenerator(ServerLevel level)
|
||||||
|
{
|
||||||
|
this.level = level;
|
||||||
|
this.levelWrapper = ServerLevelWrapper.getWrapper(level);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EDhApiWorldGeneratorReturnType getReturnType() { return EDhApiWorldGeneratorReturnType.API_CHUNKS; }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isBusy() { return false; }
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object[] generateChunk(int chunkX, int chunkZ, EDhApiDistantGeneratorMode eDhApiDistantGeneratorMode)
|
||||||
|
{
|
||||||
|
ChunkAccess chunk = this.level.getChunk(chunkX, chunkZ);
|
||||||
|
return new Object[] { chunk, this.level };
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DhApiChunk generateApiChunk(int chunkPosX, int chunkPosZ, EDhApiDistantGeneratorMode generatorMode)
|
||||||
|
{
|
||||||
|
ChunkAccess chunk = this.level.getChunk(chunkPosX, chunkPosZ);
|
||||||
|
|
||||||
|
int minBuildHeight = chunk.getMinBuildHeight();
|
||||||
|
int maxBuildHeight = chunk.getMaxBuildHeight();
|
||||||
|
|
||||||
|
DhApiChunk apiChunk = DhApiChunk.create(chunkPosX, chunkPosZ, minBuildHeight, maxBuildHeight);
|
||||||
|
for (int x = 0; x < 16; x++)
|
||||||
|
{
|
||||||
|
for (int z = 0; z < 16; z++)
|
||||||
|
{
|
||||||
|
ArrayList<DhApiTerrainDataPoint> dataPoints = new ArrayList<>();
|
||||||
|
|
||||||
|
IDhApiBlockStateWrapper block = null;
|
||||||
|
IDhApiBiomeWrapper biome = null;
|
||||||
|
|
||||||
|
for (int y = minBuildHeight; y < maxBuildHeight; y++)
|
||||||
|
{
|
||||||
|
block = DhApi.Delayed.wrapperFactory.getBlockStateWrapper(new Object[]{chunk.getBlockState(new BlockPos(x, y, z))}, this.levelWrapper);
|
||||||
|
biome = DhApi.Delayed.wrapperFactory.getBiomeWrapper(new Object[]{chunk.getNoiseBiome(x, y, z)}, this.levelWrapper);
|
||||||
|
dataPoints.add(DhApiTerrainDataPoint.create((byte) 0, 0, 15, y, y + 1, block, biome));
|
||||||
|
}
|
||||||
|
|
||||||
|
apiChunk.setDataPoints(x, z, dataPoints);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return apiChunk;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void preGeneratorTaskStart() { /* do nothing */ }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() { /* do nothing */ }
|
||||||
|
|
||||||
|
}
|
||||||
+1
-1
@@ -32,7 +32,7 @@ public class ModMenuIntegration implements ModMenuApi
|
|||||||
@Override
|
@Override
|
||||||
public ConfigScreenFactory<?> getModConfigScreenFactory()
|
public ConfigScreenFactory<?> getModConfigScreenFactory()
|
||||||
{
|
{
|
||||||
return GetConfigScreen::getScreen;
|
return parent -> GetConfigScreen.getScreen(parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -37,7 +37,7 @@ public class ModChecker implements IModChecker
|
|||||||
@Override
|
@Override
|
||||||
public File modLocation(String modid)
|
public File modLocation(String modid)
|
||||||
{
|
{
|
||||||
return new File(FabricLoader.getInstance().getModContainer(modid).get().getOrigin().getPaths().getFirst().toUri());
|
return new File(FabricLoader.getInstance().getModContainer(modid).get().getOrigin().getPaths().get(0).toUri());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+90
-93
@@ -19,20 +19,18 @@
|
|||||||
|
|
||||||
package com.seibel.distanthorizons.fabric.wrappers.modAccessor;
|
package com.seibel.distanthorizons.fabric.wrappers.modAccessor;
|
||||||
|
|
||||||
import java.util.HashSet;
|
import java.lang.invoke.MethodHandle;
|
||||||
import java.util.stream.Collectors;
|
import java.lang.invoke.MethodHandles;
|
||||||
|
import java.lang.invoke.MethodType;
|
||||||
|
|
||||||
import com.seibel.distanthorizons.core.pos.DhChunkPos;
|
|
||||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||||
import com.seibel.distanthorizons.core.util.math.Mat4f;
|
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.IWrapperFactory;
|
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.ISodiumAccessor;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.ISodiumAccessor;
|
||||||
|
|
||||||
|
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
|
#if MC_VER < MC_1_20_1
|
||||||
import me.jellysquid.mods.sodium.client.render.SodiumWorldRenderer;
|
import me.jellysquid.mods.sodium.client.render.SodiumWorldRenderer;
|
||||||
import net.minecraft.client.Minecraft;
|
#endif
|
||||||
#if MC_VER < MC_1_17_1
|
#if MC_VER < MC_1_17_1
|
||||||
import net.minecraft.nbt.CompoundTag;
|
import net.minecraft.nbt.CompoundTag;
|
||||||
import net.minecraft.network.protocol.Packet;
|
import net.minecraft.network.protocol.Packet;
|
||||||
@@ -40,101 +38,100 @@ import net.minecraft.world.entity.Entity;
|
|||||||
import net.minecraft.world.entity.EntityType;
|
import net.minecraft.world.entity.EntityType;
|
||||||
import net.minecraft.world.level.LevelAccessor;
|
import net.minecraft.world.level.LevelAccessor;
|
||||||
import net.minecraft.world.phys.AABB;
|
import net.minecraft.world.phys.AABB;
|
||||||
#else
|
#else
|
||||||
import net.minecraft.world.level.LevelHeightAccessor;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
public class SodiumAccessor implements ISodiumAccessor
|
public class SodiumAccessor implements ISodiumAccessor
|
||||||
{
|
{
|
||||||
private final IWrapperFactory factory = SingletonInjector.INSTANCE.get(IWrapperFactory.class);
|
#if MC_VER >= MC_1_20_1
|
||||||
private final IMinecraftRenderWrapper MC_RENDER = SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class);
|
private static MethodHandle setFogOcclusionMethod;
|
||||||
|
private static Object sodiumPerformanceOptions;
|
||||||
public IClientLevelWrapper levelWrapper;
|
|
||||||
public Mat4f mcModelViewMatrix;
|
|
||||||
public Mat4f mcProjectionMatrix;
|
|
||||||
public float partialTicks;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getModName()
|
|
||||||
{
|
|
||||||
return "Sodium-Fabric";
|
|
||||||
}
|
|
||||||
|
|
||||||
#if MC_VER >= MC_1_17_1
|
|
||||||
@Override
|
|
||||||
public HashSet<DhChunkPos> getNormalRenderedChunks()
|
|
||||||
{
|
|
||||||
SodiumWorldRenderer renderer = SodiumWorldRenderer.instance();
|
|
||||||
LevelHeightAccessor height = Minecraft.getInstance().level;
|
|
||||||
|
|
||||||
#if MC_VER >= MC_1_20_1
|
|
||||||
// TODO: This is just a tmp solution, use a proper solution later
|
|
||||||
return MC_RENDER.getMaximumRenderedChunks().stream().filter((DhChunkPos chunk) -> (renderer.isBoxVisible(
|
|
||||||
chunk.getMinBlockX() + 1, height.getMinBuildHeight() + 1, chunk.getMinBlockZ() + 1,
|
|
||||||
chunk.getMinBlockX() + 15, height.getMaxBuildHeight() - 1, chunk.getMinBlockZ() + 15))).collect(Collectors.toCollection(HashSet::new));
|
|
||||||
#elif MC_VER >= MC_1_18_2
|
|
||||||
// 0b11 = Lighted chunk & loaded chunk
|
|
||||||
return renderer.getChunkTracker().getChunks(0b00).filter(
|
|
||||||
(long l) -> {
|
|
||||||
return true;
|
|
||||||
}).mapToObj(DhChunkPos::new).collect(Collectors.toCollection(HashSet::new));
|
|
||||||
#else
|
|
||||||
// TODO: Maybe use a mixin to make this more efficient, and maybe ignore changes behind the camera
|
|
||||||
return MC_RENDER.getMaximumRenderedChunks().stream().filter((DhChunkPos chunk) -> {
|
|
||||||
return (renderer.isBoxVisible(
|
|
||||||
chunk.getMinBlockX() + 1, height.getMinBuildHeight() + 1, chunk.getMinBlockZ() + 1,
|
|
||||||
chunk.getMinBlockX() + 15, height.getMaxBuildHeight() - 1, chunk.getMinBlockZ() + 15));
|
|
||||||
}).collect(Collectors.toCollection(HashSet::new));
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
@Override
|
|
||||||
public HashSet<DhChunkPos> getNormalRenderedChunks() {
|
|
||||||
SodiumWorldRenderer renderer = SodiumWorldRenderer.getInstance();
|
|
||||||
LevelAccessor height = Minecraft.getInstance().level;
|
|
||||||
// TODO: Maybe use a mixin to make this more efficient
|
|
||||||
return MC_RENDER.getMaximumRenderedChunks().stream().filter((DhChunkPos chunk) -> {
|
|
||||||
FakeChunkEntity AABB = new FakeChunkEntity(chunk.x, chunk.z, height.getMaxBuildHeight());
|
|
||||||
return (renderer.isEntityVisible(AABB));
|
|
||||||
}).collect(Collectors.toCollection(HashSet::new));
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class FakeChunkEntity extends Entity {
|
|
||||||
public int cx;
|
|
||||||
public int cz;
|
|
||||||
public int my;
|
|
||||||
public FakeChunkEntity(int chunkX, int chunkZ, int maxHeight) {
|
|
||||||
super(EntityType.AREA_EFFECT_CLOUD, null);
|
|
||||||
cx = chunkX;
|
|
||||||
cz = chunkZ;
|
|
||||||
my = maxHeight;
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public AABB getBoundingBoxForCulling() {
|
|
||||||
return new AABB(cx*16+1, 1, cz*16+1,
|
|
||||||
cx*16+15, my-1, cz*16+15);
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
protected void defineSynchedData() {}
|
|
||||||
@Override
|
|
||||||
protected void readAdditionalSaveData(CompoundTag paramCompoundTag) {}
|
|
||||||
@Override
|
|
||||||
protected void addAdditionalSaveData(CompoundTag paramCompoundTag) {}
|
|
||||||
@Override
|
|
||||||
public Packet<?> getAddEntityPacket() {
|
|
||||||
throw new UnsupportedOperationException("This is a FAKE CHUNK ENTITY... For tricking the Sodium to check a AABB.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/** A temporary overwrite for a config in sodium 0.5 to fix their terrain from showing, will be removed once a proper fix is added */
|
|
||||||
// FIXME
|
|
||||||
|
//======================//
|
||||||
|
// mod accessor methods //
|
||||||
|
//======================//
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setFogOcclusion(boolean b)
|
public String getModName() { return "Sodium-Fabric"; }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//================//
|
||||||
|
// sodium methods //
|
||||||
|
//================//
|
||||||
|
|
||||||
|
/** An overwrite for a config in sodium 0.5 to fix their terrain from showing */
|
||||||
|
@Override
|
||||||
|
public void setFogOcclusion(boolean occlusionEnabled)
|
||||||
{
|
{
|
||||||
#if MC_VER >= MC_1_20_1
|
#if MC_VER >= MC_1_20_1
|
||||||
me.jellysquid.mods.sodium.client.SodiumClientMod.options().performance.useFogOcclusion = b;
|
try
|
||||||
|
{
|
||||||
|
if (sodiumPerformanceOptions == null)
|
||||||
|
{
|
||||||
|
boolean sodiumV6 = classPresent("net.caffeinemc.mods.sodium.client.render.SodiumWorldRenderer");
|
||||||
|
if (!sodiumV6)
|
||||||
|
{
|
||||||
|
// sodium 0.5
|
||||||
|
|
||||||
|
Class<?> optionsClass = Class.forName("me.jellysquid.mods.sodium.client.gui.SodiumGameOptions");
|
||||||
|
Object basicOptions = MethodHandles.lookup().findStatic(
|
||||||
|
Class.forName("me.jellysquid.mods.sodium.client.SodiumClientMod"),
|
||||||
|
"options", MethodType.methodType(optionsClass)).invoke();
|
||||||
|
sodiumPerformanceOptions = optionsClass.getDeclaredField("performance").get(basicOptions);
|
||||||
|
setFogOcclusionMethod = MethodHandles.lookup()
|
||||||
|
.findSetter(Class.forName(
|
||||||
|
"me.jellysquid.mods.sodium.client.gui.SodiumGameOptions$PerformanceSettings"),
|
||||||
|
"useFogOcclusion", boolean.class);
|
||||||
|
|
||||||
|
// alternate option if referencing Sodium 0.5 directly
|
||||||
|
//me.jellysquid.mods.sodium.client.SodiumClientMod.options().performance.useFogOcclusion = b;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// sodium 0.6
|
||||||
|
|
||||||
|
Class<?> optionsClass = Class.forName("net.caffeinemc.mods.sodium.client.gui.SodiumGameOptions");
|
||||||
|
Object basicOptions = MethodHandles.lookup().findStatic(
|
||||||
|
Class.forName("net.caffeinemc.mods.sodium.client.SodiumClientMod"),
|
||||||
|
"options", MethodType.methodType(optionsClass)).invoke();
|
||||||
|
sodiumPerformanceOptions = optionsClass.getDeclaredField("performance").get(basicOptions);
|
||||||
|
setFogOcclusionMethod = MethodHandles.lookup()
|
||||||
|
.findSetter(Class.forName(
|
||||||
|
"net.caffeinemc.mods.sodium.client.gui.SodiumGameOptions$PerformanceSettings"),
|
||||||
|
"useFogOcclusion", boolean.class);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setFogOcclusionMethod.invoke(sodiumPerformanceOptions, occlusionEnabled);
|
||||||
|
}
|
||||||
|
catch (Throwable e)
|
||||||
|
{
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//================//
|
||||||
|
// helper methods //
|
||||||
|
//================//
|
||||||
|
|
||||||
|
private static boolean classPresent(String className)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Class.forName(className);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch (ClassNotFoundException e)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,11 +10,7 @@
|
|||||||
"client": [
|
"client": [
|
||||||
"client.MixinClientLevel",
|
"client.MixinClientLevel",
|
||||||
"client.MixinClientPacketListener",
|
"client.MixinClientPacketListener",
|
||||||
"client.MixinDebugScreenOverlay",
|
|
||||||
"client.MixinFogRenderer",
|
|
||||||
"client.MixinGameRenderer",
|
|
||||||
"client.MixinLevelRenderer",
|
"client.MixinLevelRenderer",
|
||||||
"client.MixinLightTexture",
|
|
||||||
"client.MixinOptionsScreen",
|
"client.MixinOptionsScreen",
|
||||||
"client.MixinMinecraft",
|
"client.MixinMinecraft",
|
||||||
"client.MixinTextureUtil"
|
"client.MixinTextureUtil"
|
||||||
|
|||||||
@@ -35,6 +35,7 @@
|
|||||||
},
|
},
|
||||||
|
|
||||||
"mixins": [
|
"mixins": [
|
||||||
|
"DistantHorizons.common.mixins.json",
|
||||||
"DistantHorizons.fabric.mixins.json"
|
"DistantHorizons.fabric.mixins.json"
|
||||||
],
|
],
|
||||||
|
|
||||||
|
|||||||
+3
-2
@@ -28,6 +28,7 @@ loom {
|
|||||||
extraAccessWideners.add loom.accessWidenerPath.get().asFile.name
|
extraAccessWideners.add loom.accessWidenerPath.get().asFile.name
|
||||||
|
|
||||||
mixinConfigs = [
|
mixinConfigs = [
|
||||||
|
"DistantHorizons.common.mixins.json",
|
||||||
"DistantHorizons.forge.mixins.json"
|
"DistantHorizons.forge.mixins.json"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -51,8 +52,8 @@ loom {
|
|||||||
}
|
}
|
||||||
|
|
||||||
remapJar {
|
remapJar {
|
||||||
inputFile = shadeDowngradedApi.archiveFile
|
inputFile = shadowJar.archiveFile
|
||||||
dependsOn shadeDowngradedApi
|
dependsOn shadowJar
|
||||||
}
|
}
|
||||||
|
|
||||||
def addMod(path, enabled) {
|
def addMod(path, enabled) {
|
||||||
|
|||||||
-23
@@ -1,23 +0,0 @@
|
|||||||
package com.seibel.distanthorizons.forge.mixins.client;
|
|
||||||
|
|
||||||
import com.seibel.distanthorizons.core.logging.f3.F3Screen;
|
|
||||||
import net.minecraft.client.gui.components.DebugScreenOverlay;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@Mixin(DebugScreenOverlay.class)
|
|
||||||
public class MixinDebugScreenOverlay
|
|
||||||
{
|
|
||||||
|
|
||||||
@Inject(method = "getSystemInformation", at = @At("RETURN"))
|
|
||||||
private void addCustomF3(CallbackInfoReturnable<List<String>> cir)
|
|
||||||
{
|
|
||||||
List<String> messages = cir.getReturnValue();
|
|
||||||
F3Screen.addStringToDisplay(messages);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
-84
@@ -1,84 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of the Distant Horizons mod
|
|
||||||
* licensed under the GNU LGPL v3 License.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2020-2023 James Seibel
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
|
||||||
* the Free Software Foundation, version 3.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.seibel.distanthorizons.forge.mixins.client;
|
|
||||||
|
|
||||||
import com.seibel.distanthorizons.core.config.Config;
|
|
||||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
|
||||||
|
|
||||||
import com.mojang.blaze3d.systems.RenderSystem;
|
|
||||||
|
|
||||||
import net.minecraft.client.Camera;
|
|
||||||
import net.minecraft.client.renderer.FogRenderer;
|
|
||||||
import net.minecraft.client.renderer.FogRenderer.FogMode;
|
|
||||||
import net.minecraft.world.effect.MobEffects;
|
|
||||||
import net.minecraft.world.entity.Entity;
|
|
||||||
import net.minecraft.world.entity.LivingEntity;
|
|
||||||
#if MC_VER < MC_1_17_1
|
|
||||||
import net.minecraft.world.level.material.FluidState;
|
|
||||||
#else
|
|
||||||
import net.minecraft.world.level.material.FogType;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Mixin(FogRenderer.class)
|
|
||||||
public class MixinFogRenderer
|
|
||||||
{
|
|
||||||
|
|
||||||
// Using this instead of Float.MAX_VALUE because Sodium don't like it.
|
|
||||||
private static final float A_REALLY_REALLY_BIG_VALUE = 420694206942069.F;
|
|
||||||
private static final float A_EVEN_LARGER_VALUE = 42069420694206942069.F;
|
|
||||||
|
|
||||||
@Inject(at = @At("RETURN"),
|
|
||||||
method = "setupFog(Lnet/minecraft/client/Camera;Lnet/minecraft/client/renderer/FogRenderer$FogMode;FZF)V",
|
|
||||||
remap = #if MC_VER == MC_1_17_1 || MC_VER == MC_1_18_2 false #else true #endif ) // Remap messiness due to this being weird in forge
|
|
||||||
private static void disableSetupFog(Camera camera, FogMode fogMode, float f, boolean bl, float partTick, CallbackInfo callback)
|
|
||||||
{
|
|
||||||
#if MC_VER < MC_1_17_1
|
|
||||||
FluidState fluidState = camera.getFluidInCamera();
|
|
||||||
boolean cameraNotInFluid = fluidState.isEmpty();
|
|
||||||
#else
|
|
||||||
FogType fogTypes = camera.getFluidInCamera();
|
|
||||||
boolean cameraNotInFluid = fogTypes == FogType.NONE;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
Entity entity = camera.getEntity();
|
|
||||||
boolean isSpecialFog = (entity instanceof LivingEntity) && ((LivingEntity) entity).hasEffect(MobEffects.BLINDNESS);
|
|
||||||
if (!isSpecialFog && cameraNotInFluid && fogMode == FogMode.FOG_TERRAIN
|
|
||||||
&& !SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class).isFogStateSpecial()
|
|
||||||
&& Config.Client.Advanced.Graphics.Fog.disableVanillaFog.get())
|
|
||||||
{
|
|
||||||
#if MC_VER < MC_1_17_1
|
|
||||||
RenderSystem.fogStart(A_REALLY_REALLY_BIG_VALUE);
|
|
||||||
RenderSystem.fogEnd(A_EVEN_LARGER_VALUE);
|
|
||||||
#else
|
|
||||||
RenderSystem.setShaderFogStart(A_REALLY_REALLY_BIG_VALUE);
|
|
||||||
RenderSystem.setShaderFogEnd(A_EVEN_LARGER_VALUE);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
-58
@@ -1,58 +0,0 @@
|
|||||||
package com.seibel.distanthorizons.forge.mixins.client;
|
|
||||||
|
|
||||||
import com.seibel.distanthorizons.common.wrappers.DependencySetupDoneCheck;
|
|
||||||
import com.seibel.distanthorizons.core.api.internal.ClientApi;
|
|
||||||
import net.minecraft.client.renderer.GameRenderer;
|
|
||||||
import org.apache.logging.log4j.LogManager;
|
|
||||||
import org.apache.logging.log4j.Logger;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
|
||||||
|
|
||||||
// TODO: Check if this port from fabric works
|
|
||||||
@Mixin(GameRenderer.class)
|
|
||||||
public class MixinGameRenderer
|
|
||||||
{
|
|
||||||
private static final Logger LOGGER = LogManager.getLogger(MixinGameRenderer.class.getSimpleName());
|
|
||||||
|
|
||||||
#if MC_VER >= MC_1_17_1
|
|
||||||
// FIXME: This I think will dup multiple renderStartupEvent calls...
|
|
||||||
@Inject(method = {"reloadShaders", "preloadUiShader"}, at = @At("TAIL"))
|
|
||||||
public void onStartupShaders(CallbackInfo ci)
|
|
||||||
{
|
|
||||||
LOGGER.info("Starting up renderer (forge)");
|
|
||||||
if (!DependencySetupDoneCheck.isDone)
|
|
||||||
{
|
|
||||||
LOGGER.warn("Dependency setup is not done yet, skipping renderer this startup event!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
ClientApi.INSTANCE.rendererStartupEvent();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Inject(method = "shutdownShaders", at = @At("HEAD"))
|
|
||||||
public void onShutdownShaders(CallbackInfo ci)
|
|
||||||
{
|
|
||||||
LOGGER.info("Shutting down renderer (forge)");
|
|
||||||
if (!DependencySetupDoneCheck.isDone)
|
|
||||||
{
|
|
||||||
LOGGER.warn("Dependency setup is not done yet, skipping renderer this shutdown event!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
ClientApi.INSTANCE.rendererShutdownEvent();
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
|
|
||||||
|
|
||||||
@Inject(method = {"loadEffect"}, at = @At("TAIL"))
|
|
||||||
public void onStartupShaders(CallbackInfo ci) {
|
|
||||||
ClientApi.INSTANCE.rendererStartupEvent();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Inject(method = "shutdownEffect", at = @At("HEAD"))
|
|
||||||
public void onShutdownShaders(CallbackInfo ci) {
|
|
||||||
ClientApi.INSTANCE.rendererShutdownEvent();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}
|
|
||||||
-59
@@ -1,59 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of the Distant Horizons mod
|
|
||||||
* licensed under the GNU LGPL v3 License.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2020-2023 James Seibel
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
|
||||||
* the Free Software Foundation, version 3.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.seibel.distanthorizons.forge.mixins.client;
|
|
||||||
|
|
||||||
|
|
||||||
import com.mojang.blaze3d.platform.NativeImage;
|
|
||||||
|
|
||||||
import com.seibel.distanthorizons.common.wrappers.minecraft.MinecraftRenderWrapper;
|
|
||||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
|
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
|
|
||||||
import net.minecraft.client.renderer.LightTexture;
|
|
||||||
|
|
||||||
import org.spongepowered.asm.mixin.Final;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
|
||||||
|
|
||||||
@Mixin(LightTexture.class)
|
|
||||||
public class MixinLightTexture
|
|
||||||
{
|
|
||||||
@Shadow //# if MC_VER >= MC_1_20_4 (remap = false) # endif
|
|
||||||
@Final
|
|
||||||
private NativeImage lightPixels;
|
|
||||||
|
|
||||||
|
|
||||||
@Inject(method = "updateLightTexture(F)V", at = @At("RETURN"))
|
|
||||||
public void updateLightTexture(float partialTicks, CallbackInfo ci)
|
|
||||||
{
|
|
||||||
IMinecraftClientWrapper mc = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class);
|
|
||||||
if (mc == null || mc.getWrappedClientLevel() == null)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
IClientLevelWrapper clientLevel = mc.getWrappedClientLevel();
|
|
||||||
MinecraftRenderWrapper.INSTANCE.updateLightmap(this.lightPixels, clientLevel);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -9,11 +9,7 @@
|
|||||||
],
|
],
|
||||||
"client": [
|
"client": [
|
||||||
"client.MixinClientPacketListener",
|
"client.MixinClientPacketListener",
|
||||||
"client.MixinDebugScreenOverlay",
|
|
||||||
"client.MixinFogRenderer",
|
|
||||||
"client.MixinGameRenderer",
|
|
||||||
"client.MixinLevelRenderer",
|
"client.MixinLevelRenderer",
|
||||||
"client.MixinLightTexture",
|
|
||||||
"client.MixinOptionsScreen",
|
"client.MixinOptionsScreen",
|
||||||
"client.MixinTextureUtil"
|
"client.MixinTextureUtil"
|
||||||
],
|
],
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
|
||||||
networkTimeout=10000
|
networkTimeout=10000
|
||||||
validateDistributionUrl=true
|
validateDistributionUrl=true
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
|
|||||||
+15
-11
@@ -23,7 +23,7 @@ loom {
|
|||||||
mixin {
|
mixin {
|
||||||
// Mixins are defined in the `mods.toml`
|
// Mixins are defined in the `mods.toml`
|
||||||
}
|
}
|
||||||
|
|
||||||
// "runs" isn't required, but when we do need it then it can be useful
|
// "runs" isn't required, but when we do need it then it can be useful
|
||||||
runs {
|
runs {
|
||||||
client {
|
client {
|
||||||
@@ -31,7 +31,7 @@ loom {
|
|||||||
setConfigName("NeoForge Client")
|
setConfigName("NeoForge Client")
|
||||||
ideConfigGenerated(true)
|
ideConfigGenerated(true)
|
||||||
runDir("../run")
|
runDir("../run")
|
||||||
// vmArgs("-XX:-OmitStackTraceInFastThrow", minecraftMemoryJavaArg)
|
//vmArgs("-XX:-OmitStackTraceInFastThrow", minecraftMemoryJavaArg)
|
||||||
}
|
}
|
||||||
server {
|
server {
|
||||||
server()
|
server()
|
||||||
@@ -42,13 +42,7 @@ loom {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
remapJar {
|
|
||||||
inputFile = apiDowngrade.archiveFile
|
|
||||||
dependsOn apiDowngrade
|
|
||||||
// classifier null
|
|
||||||
|
|
||||||
atAccessWideners.add("distanthorizons.accesswidener")
|
|
||||||
}
|
|
||||||
|
|
||||||
def addMod(path, enabled) {
|
def addMod(path, enabled) {
|
||||||
if (enabled == "2")
|
if (enabled == "2")
|
||||||
@@ -56,21 +50,24 @@ def addMod(path, enabled) {
|
|||||||
else if (enabled == "1")
|
else if (enabled == "1")
|
||||||
dependencies { modCompileOnly(path) }
|
dependencies { modCompileOnly(path) }
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
minecraft "com.mojang:minecraft:${rootProject.minecraft_version}"
|
minecraft "com.mojang:minecraft:${rootProject.minecraft_version}"
|
||||||
mappings loom.layered() {
|
mappings loom.layered()
|
||||||
|
{
|
||||||
// Mojmap mappings
|
// Mojmap mappings
|
||||||
officialMojangMappings()
|
officialMojangMappings()
|
||||||
// Parchment mappings (it adds parameter mappings & javadoc)
|
// Parchment mappings (it adds parameter mappings & javadoc)
|
||||||
parchment("org.parchmentmc.data:parchment-${rootProject.parchment_version}@zip")
|
parchment("org.parchmentmc.data:parchment-${rootProject.parchment_version}@zip")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Neoforge
|
// Neoforge
|
||||||
neoForge "net.neoforged:neoforge:${rootProject.neoforge_version}"
|
neoForge "net.neoforged:neoforge:${rootProject.neoforge_version}"
|
||||||
addMod("curse.maven:TerraFirmaCraft-302973:4616004", rootProject.enable_terrafirmacraft)
|
addMod("curse.maven:TerraFirmaCraft-302973:4616004", rootProject.enable_terrafirmacraft)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
task deleteResources(type: Delete) {
|
task deleteResources(type: Delete) {
|
||||||
delete file("build/resources/main")
|
delete file("build/resources/main")
|
||||||
}
|
}
|
||||||
@@ -89,6 +86,13 @@ tasks.named('runClient') {
|
|||||||
finalizedBy(deleteResources)
|
finalizedBy(deleteResources)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
remapJar {
|
||||||
|
inputFile = shadowJar.archiveFile
|
||||||
|
dependsOn shadowJar
|
||||||
|
|
||||||
|
atAccessWideners.add("distanthorizons.accesswidener")
|
||||||
|
}
|
||||||
|
|
||||||
sourcesJar {
|
sourcesJar {
|
||||||
def commonSources = project(":common").sourcesJar
|
def commonSources = project(":common").sourcesJar
|
||||||
dependsOn commonSources
|
dependsOn commonSources
|
||||||
|
|||||||
@@ -129,11 +129,12 @@ public class NeoforgeClientProxy implements AbstractModInitializer.IEventProxy
|
|||||||
LOGGER.info("level load");
|
LOGGER.info("level load");
|
||||||
|
|
||||||
LevelAccessor level = event.getLevel();
|
LevelAccessor level = event.getLevel();
|
||||||
if (!(level instanceof ClientLevel clientLevel))
|
if (!(level instanceof ClientLevel))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ClientLevel clientLevel = (ClientLevel) level;
|
||||||
IClientLevelWrapper clientLevelWrapper = ClientLevelWrapper.getWrapper(clientLevel);
|
IClientLevelWrapper clientLevelWrapper = ClientLevelWrapper.getWrapper(clientLevel);
|
||||||
// TODO this causes a crash due to level being set to null somewhere
|
// TODO this causes a crash due to level being set to null somewhere
|
||||||
ClientApi.INSTANCE.clientLevelLoadEvent(clientLevelWrapper);
|
ClientApi.INSTANCE.clientLevelLoadEvent(clientLevelWrapper);
|
||||||
@@ -144,11 +145,12 @@ public class NeoforgeClientProxy implements AbstractModInitializer.IEventProxy
|
|||||||
LOGGER.info("level unload");
|
LOGGER.info("level unload");
|
||||||
|
|
||||||
LevelAccessor level = event.getLevel();
|
LevelAccessor level = event.getLevel();
|
||||||
if (!(level instanceof ClientLevel clientLevel))
|
if (!(level instanceof ClientLevel))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ClientLevel clientLevel = (ClientLevel) level;
|
||||||
IClientLevelWrapper clientLevelWrapper = ClientLevelWrapper.getWrapper(clientLevel);
|
IClientLevelWrapper clientLevelWrapper = ClientLevelWrapper.getWrapper(clientLevel);
|
||||||
ClientApi.INSTANCE.clientLevelUnloadEvent(clientLevelWrapper);
|
ClientApi.INSTANCE.clientLevelUnloadEvent(clientLevelWrapper);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ public class NeoforgeMain extends AbstractModInitializer
|
|||||||
@Override
|
@Override
|
||||||
protected void subscribeRegisterCommandsEvent(Consumer<CommandDispatcher<CommandSourceStack>> eventHandler)
|
protected void subscribeRegisterCommandsEvent(Consumer<CommandDispatcher<CommandSourceStack>> eventHandler)
|
||||||
{
|
{
|
||||||
NeoForge.EVENT_BUS.addListener((RegisterCommandsEvent e) -> eventHandler.accept(e.getDispatcher()));
|
NeoForge.EVENT_BUS.addListener((RegisterCommandsEvent e) -> { eventHandler.accept(e.getDispatcher()); });
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -100,7 +100,7 @@ public class NeoforgeMain extends AbstractModInitializer
|
|||||||
@Override
|
@Override
|
||||||
protected void subscribeServerStartingEvent(Consumer<MinecraftServer> eventHandler)
|
protected void subscribeServerStartingEvent(Consumer<MinecraftServer> eventHandler)
|
||||||
{
|
{
|
||||||
NeoForge.EVENT_BUS.addListener((ServerStartingEvent e) -> eventHandler.accept(e.getServer()));
|
NeoForge.EVENT_BUS.addListener((ServerStartingEvent e) -> { eventHandler.accept(e.getServer()); });
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
-23
@@ -1,23 +0,0 @@
|
|||||||
package com.seibel.distanthorizons.neoforge.mixins.client;
|
|
||||||
|
|
||||||
import com.seibel.distanthorizons.core.logging.f3.F3Screen;
|
|
||||||
import net.minecraft.client.gui.components.DebugScreenOverlay;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@Mixin(DebugScreenOverlay.class)
|
|
||||||
public class MixinDebugScreenOverlay
|
|
||||||
{
|
|
||||||
|
|
||||||
@Inject(method = "getSystemInformation", at = @At("RETURN"))
|
|
||||||
private void addCustomF3(CallbackInfoReturnable<List<String>> cir)
|
|
||||||
{
|
|
||||||
List<String> messages = cir.getReturnValue();
|
|
||||||
F3Screen.addStringToDisplay(messages);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
-84
@@ -1,84 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of the Distant Horizons mod
|
|
||||||
* licensed under the GNU LGPL v3 License.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2020-2023 James Seibel
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
|
||||||
* the Free Software Foundation, version 3.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.seibel.distanthorizons.neoforge.mixins.client;
|
|
||||||
|
|
||||||
import com.seibel.distanthorizons.core.config.Config;
|
|
||||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
|
||||||
|
|
||||||
import com.mojang.blaze3d.systems.RenderSystem;
|
|
||||||
|
|
||||||
import net.minecraft.client.Camera;
|
|
||||||
import net.minecraft.client.renderer.FogRenderer;
|
|
||||||
import net.minecraft.client.renderer.FogRenderer.FogMode;
|
|
||||||
import net.minecraft.world.effect.MobEffects;
|
|
||||||
import net.minecraft.world.entity.Entity;
|
|
||||||
import net.minecraft.world.entity.LivingEntity;
|
|
||||||
#if MC_VER < MC_1_17_1
|
|
||||||
import net.minecraft.world.level.material.FluidState;
|
|
||||||
#else
|
|
||||||
import net.minecraft.world.level.material.FogType;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Mixin(FogRenderer.class)
|
|
||||||
public class MixinFogRenderer
|
|
||||||
{
|
|
||||||
|
|
||||||
// Using this instead of Float.MAX_VALUE because Sodium don't like it.
|
|
||||||
private static final float A_REALLY_REALLY_BIG_VALUE = 420694206942069.F;
|
|
||||||
private static final float A_EVEN_LARGER_VALUE = 42069420694206942069.F;
|
|
||||||
|
|
||||||
@Inject(at = @At("RETURN"),
|
|
||||||
method = "setupFog(Lnet/minecraft/client/Camera;Lnet/minecraft/client/renderer/FogRenderer$FogMode;FZF)V",
|
|
||||||
remap = #if MC_VER == MC_1_17_1 || MC_VER == MC_1_18_2 false #else true #endif ) // Remap messiness due to this being weird in forge
|
|
||||||
private static void disableSetupFog(Camera camera, FogMode fogMode, float f, boolean bl, float partTick, CallbackInfo callback)
|
|
||||||
{
|
|
||||||
#if MC_VER < MC_1_17_1
|
|
||||||
FluidState fluidState = camera.getFluidInCamera();
|
|
||||||
boolean cameraNotInFluid = fluidState.isEmpty();
|
|
||||||
#else
|
|
||||||
FogType fogTypes = camera.getFluidInCamera();
|
|
||||||
boolean cameraNotInFluid = fogTypes == FogType.NONE;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
Entity entity = camera.getEntity();
|
|
||||||
boolean isSpecialFog = (entity instanceof LivingEntity) && ((LivingEntity) entity).hasEffect(MobEffects.BLINDNESS);
|
|
||||||
if (!isSpecialFog && cameraNotInFluid && fogMode == FogMode.FOG_TERRAIN
|
|
||||||
&& !SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class).isFogStateSpecial()
|
|
||||||
&& Config.Client.Advanced.Graphics.Fog.disableVanillaFog.get())
|
|
||||||
{
|
|
||||||
#if MC_VER < MC_1_17_1
|
|
||||||
RenderSystem.fogStart(A_REALLY_REALLY_BIG_VALUE);
|
|
||||||
RenderSystem.fogEnd(A_EVEN_LARGER_VALUE);
|
|
||||||
#else
|
|
||||||
RenderSystem.setShaderFogStart(A_REALLY_REALLY_BIG_VALUE);
|
|
||||||
RenderSystem.setShaderFogEnd(A_EVEN_LARGER_VALUE);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
-58
@@ -1,58 +0,0 @@
|
|||||||
package com.seibel.distanthorizons.neoforge.mixins.client;
|
|
||||||
|
|
||||||
import com.seibel.distanthorizons.common.wrappers.DependencySetupDoneCheck;
|
|
||||||
import com.seibel.distanthorizons.core.api.internal.ClientApi;
|
|
||||||
import net.minecraft.client.renderer.GameRenderer;
|
|
||||||
import org.apache.logging.log4j.LogManager;
|
|
||||||
import org.apache.logging.log4j.Logger;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
|
||||||
|
|
||||||
// TODO: Check if this port from fabric works
|
|
||||||
@Mixin(GameRenderer.class)
|
|
||||||
public class MixinGameRenderer
|
|
||||||
{
|
|
||||||
private static final Logger LOGGER = LogManager.getLogger(MixinGameRenderer.class.getSimpleName());
|
|
||||||
|
|
||||||
#if MC_VER >= MC_1_17_1
|
|
||||||
// FIXME: This I think will dup multiple renderStartupEvent calls...
|
|
||||||
@Inject(method = {"reloadShaders", "preloadUiShader"}, at = @At("TAIL"))
|
|
||||||
public void onStartupShaders(CallbackInfo ci)
|
|
||||||
{
|
|
||||||
LOGGER.info("Starting up renderer (forge)");
|
|
||||||
if (!DependencySetupDoneCheck.isDone)
|
|
||||||
{
|
|
||||||
LOGGER.warn("Dependency setup is not done yet, skipping renderer this startup event!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
ClientApi.INSTANCE.rendererStartupEvent();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Inject(method = "shutdownShaders", at = @At("HEAD"))
|
|
||||||
public void onShutdownShaders(CallbackInfo ci)
|
|
||||||
{
|
|
||||||
LOGGER.info("Shutting down renderer (forge)");
|
|
||||||
if (!DependencySetupDoneCheck.isDone)
|
|
||||||
{
|
|
||||||
LOGGER.warn("Dependency setup is not done yet, skipping renderer this shutdown event!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
ClientApi.INSTANCE.rendererShutdownEvent();
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
|
|
||||||
|
|
||||||
@Inject(method = {"loadEffect"}, at = @At("TAIL"))
|
|
||||||
public void onStartupShaders(CallbackInfo ci) {
|
|
||||||
ClientApi.INSTANCE.rendererStartupEvent();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Inject(method = "shutdownEffect", at = @At("HEAD"))
|
|
||||||
public void onShutdownShaders(CallbackInfo ci) {
|
|
||||||
ClientApi.INSTANCE.rendererShutdownEvent();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}
|
|
||||||
-59
@@ -1,59 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of the Distant Horizons mod
|
|
||||||
* licensed under the GNU LGPL v3 License.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2020-2023 James Seibel
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
|
||||||
* the Free Software Foundation, version 3.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.seibel.distanthorizons.neoforge.mixins.client;
|
|
||||||
|
|
||||||
|
|
||||||
import com.mojang.blaze3d.platform.NativeImage;
|
|
||||||
|
|
||||||
import com.seibel.distanthorizons.common.wrappers.minecraft.MinecraftRenderWrapper;
|
|
||||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
|
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
|
|
||||||
import net.minecraft.client.renderer.LightTexture;
|
|
||||||
|
|
||||||
import org.spongepowered.asm.mixin.Final;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
|
||||||
|
|
||||||
@Mixin(LightTexture.class)
|
|
||||||
public class MixinLightTexture
|
|
||||||
{
|
|
||||||
@Shadow
|
|
||||||
@Final
|
|
||||||
private NativeImage lightPixels;
|
|
||||||
|
|
||||||
|
|
||||||
@Inject(method = "updateLightTexture(F)V", at = @At("RETURN"))
|
|
||||||
public void updateLightTexture(float partialTicks, CallbackInfo ci)
|
|
||||||
{
|
|
||||||
IMinecraftClientWrapper mc = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class);
|
|
||||||
if (mc == null || mc.getWrappedClientLevel() == null)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
IClientLevelWrapper clientLevel = mc.getWrappedClientLevel();
|
|
||||||
MinecraftRenderWrapper.INSTANCE.updateLightmap(this.lightPixels, clientLevel);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
+1
-1
@@ -86,7 +86,7 @@ public class MixinMinecraft
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
versionId = GitlabGetter.INSTANCE.projectPipelines.getFirst().get("sha");
|
versionId = GitlabGetter.INSTANCE.projectPipelines.get(0).get("sha");
|
||||||
}
|
}
|
||||||
|
|
||||||
Minecraft.getInstance().setScreen(new UpdateModScreen(
|
Minecraft.getInstance().setScreen(new UpdateModScreen(
|
||||||
|
|||||||
+3
-3
@@ -104,14 +104,14 @@ public class MixinOptionsScreen extends Screen
|
|||||||
|
|
||||||
// add the button to the correct location in the UI
|
// add the button to the correct location in the UI
|
||||||
// TODO is there a better way to do this instead of using access transformers to inject into the exact UI elements?
|
// TODO is there a better way to do this instead of using access transformers to inject into the exact UI elements?
|
||||||
LinearLayout layout = (LinearLayout) this.layout.headerFrame.children.getFirst().child;
|
LinearLayout layout = (LinearLayout) this.layout.headerFrame.children.get(0).child;
|
||||||
|
|
||||||
// determine how wide the other option buttons are so we can put our botton to the left of them all
|
// determine how wide the other option buttons are so we can put our botton to the left of them all
|
||||||
AtomicInteger width = new AtomicInteger(0);
|
AtomicInteger width = new AtomicInteger(0);
|
||||||
layout.visitChildren(x -> width.addAndGet(x.getWidth()));
|
layout.visitChildren(x -> { width.addAndGet(x.getWidth()); });
|
||||||
width.addAndGet(-10); // padding between the DH button and the FOV slider
|
width.addAndGet(-10); // padding between the DH button and the FOV slider
|
||||||
|
|
||||||
layout.wrapped.addChild(this.getOptionsButton(), 1, 2, (settings) -> settings.paddingLeft(width.get() * -1));
|
layout.wrapped.addChild(this.getOptionsButton(), 1, 2, (settings) -> { settings.paddingLeft(width.get() * -1); });
|
||||||
layout.arrangeElements();
|
layout.arrangeElements();
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -9,11 +9,7 @@
|
|||||||
],
|
],
|
||||||
"client": [
|
"client": [
|
||||||
"client.MixinClientPacketListener",
|
"client.MixinClientPacketListener",
|
||||||
"client.MixinDebugScreenOverlay",
|
|
||||||
"client.MixinFogRenderer",
|
|
||||||
"client.MixinGameRenderer",
|
|
||||||
"client.MixinLevelRenderer",
|
"client.MixinLevelRenderer",
|
||||||
"client.MixinLightTexture",
|
|
||||||
"client.MixinOptionsScreen",
|
"client.MixinOptionsScreen",
|
||||||
"client.MixinTextureUtil"
|
"client.MixinTextureUtil"
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -24,6 +24,8 @@ issueTrackerURL = "${issues}"
|
|||||||
acceptableRemoteVersions = "*"
|
acceptableRemoteVersions = "*"
|
||||||
|
|
||||||
# We may need this to make forge (lexforge) & neoforge work together
|
# We may need this to make forge (lexforge) & neoforge work together
|
||||||
|
[[mixins]]
|
||||||
|
config = "DistantHorizons.common.mixins.json"
|
||||||
[[mixins]]
|
[[mixins]]
|
||||||
config = "DistantHorizons.neoforge.mixins.json"
|
config = "DistantHorizons.neoforge.mixins.json"
|
||||||
|
|
||||||
|
|||||||
@@ -33,12 +33,6 @@ pluginManagement {
|
|||||||
name "ParchmentMC"
|
name "ParchmentMC"
|
||||||
url "https://maven.parchmentmc.org"
|
url "https://maven.parchmentmc.org"
|
||||||
}
|
}
|
||||||
maven { // Used for downgrading Java versions
|
|
||||||
url "https://maven.wagyourtail.xyz/releases"
|
|
||||||
}
|
|
||||||
maven {
|
|
||||||
url "https://maven.wagyourtail.xyz/snapshots"
|
|
||||||
}
|
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
gradlePluginPortal()
|
gradlePluginPortal()
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ fabric_api_version=0.90.4+1.20.1
|
|||||||
immersive_portals_version=
|
immersive_portals_version=
|
||||||
canvas_version=
|
canvas_version=
|
||||||
|
|
||||||
fabric_incompatibility_list={ "iris": "<=1.6.20" }
|
fabric_incompatibility_list={ "iris": "<=1.7.4" }
|
||||||
fabric_recommend_list={}
|
fabric_recommend_list={}
|
||||||
|
|
||||||
# Fabric mod run
|
# Fabric mod run
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ fabric_api_version=0.90.4+1.20.2
|
|||||||
immersive_portals_version=
|
immersive_portals_version=
|
||||||
canvas_version=
|
canvas_version=
|
||||||
|
|
||||||
fabric_incompatibility_list={ "iris": "<=1.6.20" }
|
fabric_incompatibility_list={ "iris": "<=1.7.4" }
|
||||||
fabric_recommend_list={}
|
fabric_recommend_list={}
|
||||||
|
|
||||||
# Fabric mod run
|
# Fabric mod run
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ fabric_api_version=0.91.2+1.20.4
|
|||||||
immersive_portals_version=
|
immersive_portals_version=
|
||||||
canvas_version=
|
canvas_version=
|
||||||
|
|
||||||
fabric_incompatibility_list={ "iris": "<=1.6.20" }
|
fabric_incompatibility_list={ "iris": "<=1.7.4" }
|
||||||
fabric_recommend_list={}
|
fabric_recommend_list={}
|
||||||
|
|
||||||
# Fabric mod run
|
# Fabric mod run
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ fabric_api_version=0.97.8+1.20.6
|
|||||||
immersive_portals_version=
|
immersive_portals_version=
|
||||||
canvas_version=
|
canvas_version=
|
||||||
|
|
||||||
fabric_incompatibility_list={ "iris": "<=1.6.20" }
|
fabric_incompatibility_list={ "iris": "<=1.7.4" }
|
||||||
fabric_recommend_list={}
|
fabric_recommend_list={}
|
||||||
|
|
||||||
# Fabric mod run
|
# Fabric mod run
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ fabric_api_version=0.100.1+1.21
|
|||||||
immersive_portals_version=
|
immersive_portals_version=
|
||||||
canvas_version=
|
canvas_version=
|
||||||
|
|
||||||
fabric_incompatibility_list={ "iris": "<=1.6.20" }
|
fabric_incompatibility_list={ "iris": "<=1.7.4" }
|
||||||
fabric_recommend_list={}
|
fabric_recommend_list={}
|
||||||
|
|
||||||
# Fabric mod run
|
# Fabric mod run
|
||||||
|
|||||||
Reference in New Issue
Block a user