Compare commits
236 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f67fb1758d | |||
| 506ba05b34 | |||
| 70be3f9364 | |||
| 3a01151137 | |||
| 197051747a | |||
| 45efeb96fa | |||
| e05dff3fb9 | |||
| 106d97e0a1 | |||
| 34412305d0 | |||
| 6a418de153 | |||
| 41c6b2936b | |||
| 97130d1535 | |||
| d61dcfaab6 | |||
| 3c3f1ef41b | |||
| ed1d6396fd | |||
| 518ec18362 | |||
| 5715cd9266 | |||
| 56953efabc | |||
| 351802de4c | |||
| f60e74c838 | |||
| 2007a6af24 | |||
| 4bc199fe14 | |||
| bcd9a0da2c | |||
| 50c97e3ca3 | |||
| 7539cb94d4 | |||
| 3a20329096 | |||
| 702002c540 | |||
| 7f790e2c9c | |||
| b3f8b03fdf | |||
| 3597d69fa4 | |||
| ab10265150 | |||
| 671ee84136 | |||
| c489cebae3 | |||
| e55eeda1ac | |||
| 0086f40053 | |||
| 71bb151e61 | |||
| a71ceac15d | |||
| ada36c34c7 | |||
| 3cfb4386d9 | |||
| 352d0f4759 | |||
| d158a89592 | |||
| 9cc826f8a9 | |||
| 22a4c6bc79 | |||
| 20b9f4f1cb | |||
| 5c0c1c5e20 | |||
| 69645994c9 | |||
| fdcbb0594d | |||
| e5711b4ddb | |||
| cb1a617b92 | |||
| 4187eaf112 | |||
| 084de2b3f1 | |||
| 7b0a9d4843 | |||
| c42f800db5 | |||
| 300ef3745f | |||
| 5a9fdb3314 | |||
| 8708ca3048 | |||
| 9cfdbdc0ca | |||
| 48f82b0966 | |||
| 75f7ef0085 | |||
| 270776a782 | |||
| 21fff72521 | |||
| a860a9740d | |||
| a2105699fa | |||
| ea4838c791 | |||
| 9168543945 | |||
| 460996d8cd | |||
| c3948abc40 | |||
| 8ed902f6f2 | |||
| 15dda30050 | |||
| 26428ff905 | |||
| 4419ab4b8c | |||
| 5d50994beb | |||
| ce9f843048 | |||
| 8c934b4982 | |||
| 9ae41865f3 | |||
| ade7a8d8dc | |||
| 461dad9fe8 | |||
| b832e77ac2 | |||
| 66c41e49db | |||
| 0f968255e0 | |||
| ed50161cfd | |||
| 7e18acdb8f | |||
| 5c05fdd9fa | |||
| afca4d837f | |||
| 6db3795fa5 | |||
| 21fe38da8e | |||
| 340c0bc586 | |||
| 77c7ebc0d0 | |||
| f55cb4b320 | |||
| 9d3c88f0b2 | |||
| e397a3e47a | |||
| 4ff315de91 | |||
| 2fb1c43d7c | |||
| 58b5fac20b | |||
| ec238d29c6 | |||
| dac36c9e34 | |||
| caca05c0f0 | |||
| 5ce7eae7c0 | |||
| 2c38401637 | |||
| 489fe753f5 | |||
| 2293afc2d3 | |||
| b48adeb3e3 | |||
| 438186cb70 | |||
| c86ff4acae | |||
| e27e1bc2d7 | |||
| 336bf2ea26 | |||
| e72c08b0bc | |||
| 4ced316304 | |||
| c84ee721e3 | |||
| c46c056980 | |||
| d486878876 | |||
| b0b0b38bf8 | |||
| 9e43896864 | |||
| d09ddf57d3 | |||
| 486edac1d8 | |||
| 3b3731a137 | |||
| 563ec70154 | |||
| 175f5ed6d6 | |||
| 1e63607233 | |||
| 4dd8be23fa | |||
| 7fac5b4c6e | |||
| f2ec1ecf3f | |||
| 2674e6b2e9 | |||
| bcbe3f0fb7 | |||
| f85108ed11 | |||
| 2bc5169ce5 | |||
| 1edd809708 | |||
| 475111b38b | |||
| b44a967e56 | |||
| acea685e75 | |||
| 20f15a6b39 | |||
| debf52418c | |||
| cf71491381 | |||
| 0a4a8466cf | |||
| 31fac60d34 | |||
| c335020c2f | |||
| 4db4f2fbc6 | |||
| f9f4a208e7 | |||
| b5fa5936b3 | |||
| 6ceabe7895 | |||
| ec3d8afbfc | |||
| e9a0c6d097 | |||
| 0238568370 | |||
| 74be00e025 | |||
| c10af6dd04 | |||
| 85ee5ac833 | |||
| 21877d67a5 | |||
| ae33a79d6e | |||
| 9204b357d8 | |||
| 78b1b74036 | |||
| 864c5b5f86 | |||
| b271c8e119 | |||
| 79bdae5b8b | |||
| d5dc9f6b79 | |||
| a50f13caa0 | |||
| 75b3649a97 | |||
| 69adb54b91 | |||
| 458c1ae7e0 | |||
| a647551d26 | |||
| 3a45bdd2a2 | |||
| 4806cd2445 | |||
| af7f90f128 | |||
| f72ad60f58 | |||
| 6015afbf4c | |||
| 0369ae63f3 | |||
| 278d5063fb | |||
| a64e72034e | |||
| fcdb56660c | |||
| 0c26261cd5 | |||
| b50525fff9 | |||
| 92e403823b | |||
| e02f56f4ef | |||
| aa4681e044 | |||
| 1c9130c3f1 | |||
| c3597cd843 | |||
| d4a52ac5a3 | |||
| 1b9d14e7b4 | |||
| 0ea27b676e | |||
| cd73608b07 | |||
| 03fc22f611 | |||
| cc251e46b0 | |||
| 7aa0bfefec | |||
| 9bdad5e4f1 | |||
| baebb7323d | |||
| 8a3175f345 | |||
| dc58efb301 | |||
| c9ac4b2ada | |||
| 6e1ec476ed | |||
| d1aa5a524b | |||
| 5c661a3a76 | |||
| d29e9085a1 | |||
| d392de3c0d | |||
| 7209193f8f | |||
| ed4f644a3f | |||
| 34038684a7 | |||
| 6fe6694c82 | |||
| 8e52f1aca5 | |||
| 5ce3dda2d5 | |||
| f4f81f4d7f | |||
| 7c37a5c370 | |||
| b495ac4799 | |||
| 2ddeaf50eb | |||
| 3721ebea6e | |||
| 98f8a87362 | |||
| 10a743ddef | |||
| 95c896f964 | |||
| 040bc16874 | |||
| 35d3fdb473 | |||
| 549f7510f7 | |||
| fab64d8477 | |||
| 4a6a35f617 | |||
| 2b519a826f | |||
| 445c01b5ae | |||
| 0f08bd540e | |||
| 77088465f9 | |||
| affe014433 | |||
| 4c06bf6dbd | |||
| dcab616385 | |||
| 89b7d08e9b | |||
| 724e318221 | |||
| a40d62d46a | |||
| 2f6b4c079b | |||
| 951e3c0271 | |||
| 84825c2d09 | |||
| ec627e2eba | |||
| 06bc9a349f | |||
| ff6c4e227b | |||
| a4d46ffe94 | |||
| bd5c140782 | |||
| 229c3f7c91 | |||
| 693369bc08 | |||
| d109fe6c43 | |||
| 3c9d3707cf | |||
| 6e53564835 | |||
| 2480fe0d86 | |||
| 691c9d3f45 |
+1
-2
@@ -5,7 +5,6 @@ root = true
|
|||||||
|
|
||||||
[*]
|
[*]
|
||||||
charset = utf-8
|
charset = utf-8
|
||||||
end_of_line = crlf
|
|
||||||
indent_size = 4
|
indent_size = 4
|
||||||
indent_style = space
|
indent_style = space
|
||||||
insert_final_newline = false
|
insert_final_newline = false
|
||||||
@@ -688,7 +687,7 @@ ij_markdown_wrap_text_inside_blockquotes = true
|
|||||||
ij_toml_keep_indents_on_empty_lines = false
|
ij_toml_keep_indents_on_empty_lines = false
|
||||||
|
|
||||||
[{*.yaml,*.yml}]
|
[{*.yaml,*.yml}]
|
||||||
indent_size = 2
|
indent_size = 4
|
||||||
ij_yaml_align_values_properties = do_not_align
|
ij_yaml_align_values_properties = do_not_align
|
||||||
ij_yaml_autoinsert_sequence_marker = true
|
ij_yaml_autoinsert_sequence_marker = true
|
||||||
ij_yaml_block_mapping_on_new_line = false
|
ij_yaml_block_mapping_on_new_line = false
|
||||||
|
|||||||
@@ -29,7 +29,6 @@ buildAllJars/
|
|||||||
relocate_natives/.venv/
|
relocate_natives/.venv/
|
||||||
relocate_natives/__pycache__/
|
relocate_natives/__pycache__/
|
||||||
relocate_natives/apple-codesign/
|
relocate_natives/apple-codesign/
|
||||||
relocate_natives/cache/
|
|
||||||
|
|
||||||
# file from notepad++
|
# file from notepad++
|
||||||
*.bak
|
*.bak
|
||||||
|
|||||||
+9
-5
@@ -17,9 +17,6 @@ variables:
|
|||||||
# These can be extended so code is a bit less duplicated
|
# These can be extended so code is a bit less duplicated
|
||||||
.build_java:
|
.build_java:
|
||||||
#image: eclipse-temurin:17
|
#image: eclipse-temurin:17
|
||||||
before_script:
|
|
||||||
- apt-get update
|
|
||||||
- apt-get install python3 python3-pip python-is-python3 python3-venv -y --no-install-recommends
|
|
||||||
cache:
|
cache:
|
||||||
key: "gradleCache_$CI_JOB_NAME_SLUG"
|
key: "gradleCache_$CI_JOB_NAME_SLUG"
|
||||||
policy: pull-push
|
policy: pull-push
|
||||||
@@ -38,13 +35,20 @@ build:
|
|||||||
stage: build
|
stage: build
|
||||||
parallel:
|
parallel:
|
||||||
matrix:
|
matrix:
|
||||||
- MC_VER: ["1.16.5", "1.17.1", "1.18.2", "1.19.2", "1.19.4", "1.20.1", "1.20.2", "1.20.4", "1.20.6", "1.21.1", "1.21.3", "1.21.4"]
|
- MC_VER: [
|
||||||
|
"1.21.10", "1.21.9", "1.21.8", "1.21.6", "1.21.5", "1.21.4", "1.21.3", "1.21.1",
|
||||||
|
"1.20.6", "1.20.4", "1.20.2", "1.20.1",
|
||||||
|
"1.19.4", "1.19.2",
|
||||||
|
"1.18.2",
|
||||||
|
"1.17.1",
|
||||||
|
"1.16.5"
|
||||||
|
]
|
||||||
script:
|
script:
|
||||||
# this both runs the unit tests and assembles the code
|
# this both runs the unit tests and assembles the code
|
||||||
- ./gradlew clean -PmcVer="${MC_VER}" -PinfoGitCommit="${CI_COMMIT_SHA}" -PinfoGitBranch="${CI_COMMIT_BRANCH}" -PinfoBuildSource="GitLab CI (${CI_PIPELINE_ID})" --gradle-user-home cache/;
|
- ./gradlew clean -PmcVer="${MC_VER}" -PinfoGitCommit="${CI_COMMIT_SHA}" -PinfoGitBranch="${CI_COMMIT_BRANCH}" -PinfoBuildSource="GitLab CI (${CI_PIPELINE_ID})" --gradle-user-home cache/;
|
||||||
- ./gradlew build -PmcVer="${MC_VER}" -PinfoGitCommit="${CI_COMMIT_SHA}" -PinfoGitBranch="${CI_COMMIT_BRANCH}" -PinfoBuildSource="GitLab CI (${CI_PIPELINE_ID})" --gradle-user-home cache/;
|
- ./gradlew build -PmcVer="${MC_VER}" -PinfoGitCommit="${CI_COMMIT_SHA}" -PinfoGitBranch="${CI_COMMIT_BRANCH}" -PinfoBuildSource="GitLab CI (${CI_PIPELINE_ID})" --gradle-user-home cache/;
|
||||||
- ./gradlew mergeJars -PmcVer="${MC_VER}" -PinfoGitCommit="${CI_COMMIT_SHA}" -PinfoGitBranch="${CI_COMMIT_BRANCH}" -PinfoBuildSource="GitLab CI (${CI_PIPELINE_ID})" --gradle-user-home cache/;
|
- ./gradlew mergeJars -PmcVer="${MC_VER}" -PinfoGitCommit="${CI_COMMIT_SHA}" -PinfoGitBranch="${CI_COMMIT_BRANCH}" -PinfoBuildSource="GitLab CI (${CI_PIPELINE_ID})" --gradle-user-home cache/;
|
||||||
- cp ./fabric/build/libs/* ./forge/build/libs/* ./neoforge/build/libs/* ./Merged/* . || true
|
- cp ./fabric/build/libs/* ./forge/build/libs/* ./neoforge/build/libs/* ./build/merged/* . || true
|
||||||
artifacts:
|
artifacts:
|
||||||
name: "NightlyBuild_${MC_VER}-${CI_COMMIT_SHORT_SHA}-${CI_COMMIT_TIMESTAMP}"
|
name: "NightlyBuild_${MC_VER}-${CI_COMMIT_SHORT_SHA}-${CI_COMMIT_TIMESTAMP}"
|
||||||
paths:
|
paths:
|
||||||
|
|||||||
+17
-79
@@ -13,13 +13,13 @@ plugins {
|
|||||||
id "com.github.johnrengelman.shadow" version '8.1.1' apply false
|
id "com.github.johnrengelman.shadow" version '8.1.1' apply false
|
||||||
|
|
||||||
// Plugin to create merged jars
|
// Plugin to create merged jars
|
||||||
id "io.github.pacifistmc.forgix" version "1.2.9"
|
id "io.github.pacifistmc.forgix" version "1.3.4"
|
||||||
|
|
||||||
// Manifold preprocessor
|
// Manifold preprocessor
|
||||||
id "systems.manifold.manifold-gradle-plugin" version "0.0.2-alpha"
|
id "systems.manifold.manifold-gradle-plugin" version "0.0.2-alpha"
|
||||||
|
|
||||||
// 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.7-SNAPSHOT" apply false
|
id "dev.architectury.loom" version "1.11-SNAPSHOT" apply false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -42,8 +42,10 @@ def writeBuildGradlePredefine(List<String> mcVers, int mcIndex)
|
|||||||
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");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -67,63 +69,16 @@ project.gradle.ext.getProperties().each { prop ->
|
|||||||
// Sets up manifold stuff
|
// Sets up manifold stuff
|
||||||
writeBuildGradlePredefine(rootProject.mcVers, rootProject.mcIndex)
|
writeBuildGradlePredefine(rootProject.mcVers, rootProject.mcIndex)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Sets up the version string (the name we use for our jar)
|
// Sets up the version string (the name we use for our jar)
|
||||||
rootProject.versionStr = rootProject.mod_version + "-" + rootProject.minecraft_version // + "-" + new Date().format("yyyy_MM_dd_HH_mm")
|
rootProject.versionStr = rootProject.mod_version + "-" + rootProject.minecraft_version // + "-" + new Date().format("yyyy_MM_dd_HH_mm")
|
||||||
// Forgix settings (used for merging jars)
|
|
||||||
forgix {
|
|
||||||
|
|
||||||
String loaderHyphenSeparatedList = ((String)gradle.builds_for).replaceAll(",", "-");
|
|
||||||
|
|
||||||
group = "com.seibel.distanthorizons"
|
|
||||||
mergedJarName = "DistantHorizons-${loaderHyphenSeparatedList}-${rootProject.versionStr}.jar"
|
|
||||||
|
|
||||||
if (findProject(":forge"))
|
|
||||||
forge {
|
|
||||||
jarLocation = "build/libs/DistantHorizons-forge-${rootProject.versionStr}.jar"
|
|
||||||
}
|
|
||||||
|
|
||||||
if (findProject(":neoforge"))
|
|
||||||
custom {
|
|
||||||
projectName = "neoforge"
|
|
||||||
jarLocation = "build/libs/DistantHorizons-neoforge-${rootProject.versionStr}.jar"
|
|
||||||
}
|
|
||||||
|
|
||||||
if (findProject(":fabric"))
|
|
||||||
fabric {
|
|
||||||
jarLocation = "build/libs/DistantHorizons-fabric-${rootProject.versionStr}.jar"
|
|
||||||
}
|
|
||||||
|
|
||||||
if (findProject(":quilt"))
|
|
||||||
quilt {
|
|
||||||
jarLocation = "build/libs/DistantHorizons-quilt-${rootProject.versionStr}.jar"
|
|
||||||
}
|
|
||||||
|
|
||||||
removeDuplicate "com.seibel.distanthorizons"
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class NativeTransformer implements Transformer {
|
class NativeTransformer implements Transformer {
|
||||||
private boolean enabled = false
|
|
||||||
private final HashMap<String, String> replacements = new HashMap()
|
private final HashMap<String, String> replacements = new HashMap()
|
||||||
private final HashMap<String, byte[]> rewrittenFiles = new HashMap()
|
private final HashMap<String, byte[]> rewrittenFiles = new HashMap()
|
||||||
private var nativeRelocator
|
private var nativeRelocator
|
||||||
|
|
||||||
public File rootDir
|
public File rootDir
|
||||||
|
|
||||||
NativeTransformer() {
|
|
||||||
try {
|
|
||||||
int exitCode = Runtime.getRuntime().exec(new String[]{"python", "--version"}).waitFor()
|
|
||||||
if (exitCode == 0) {
|
|
||||||
enabled = true
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
println(e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void relocateNative(String target, String replacement) {
|
void relocateNative(String target, String replacement) {
|
||||||
if (replacement.length() > target.length()) {
|
if (replacement.length() > target.length()) {
|
||||||
throw new GradleException("Length of value \"${replacement}\" exceeds the length of \"${target}\": ${replacement.length()} > ${target.length()}")
|
throw new GradleException("Length of value \"${replacement}\" exceeds the length of \"${target}\": ${replacement.length()} > ${target.length()}")
|
||||||
@@ -132,22 +87,15 @@ class NativeTransformer implements Transformer {
|
|||||||
replacements.put(target, replacement)
|
replacements.put(target, replacement)
|
||||||
}
|
}
|
||||||
|
|
||||||
void before(Closure closure) {
|
|
||||||
if (enabled)
|
|
||||||
closure.run()
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
boolean canTransformResource(@Nonnull FileTreeElement element) {
|
boolean canTransformResource(@Nonnull FileTreeElement element) {
|
||||||
return enabled && replacements.keySet().stream().anyMatch {
|
return replacements.keySet().stream().anyMatch {
|
||||||
element.name.startsWith(it as String)
|
element.name.startsWith(it as String)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void transform(@Nonnull TransformerContext context) {
|
void transform(@Nonnull TransformerContext context) {
|
||||||
println("Transforming $context.path...")
|
|
||||||
byte[] content = context.is.readAllBytes()
|
byte[] content = context.is.readAllBytes()
|
||||||
|
|
||||||
if (nativeRelocator == null) {
|
if (nativeRelocator == null) {
|
||||||
@@ -299,7 +247,8 @@ 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}")
|
||||||
|
|
||||||
|
forgeShadowMe("com.github.luben:zstd-jni:${rootProject.zstd_version}")
|
||||||
|
|
||||||
// Compression
|
// Compression
|
||||||
forgeShadowMe("org.lz4:lz4-java:${rootProject.lz4_version}") // LZ4
|
forgeShadowMe("org.lz4:lz4-java:${rootProject.lz4_version}") // LZ4
|
||||||
@@ -395,16 +344,13 @@ subprojects { p ->
|
|||||||
// Sqlite Database
|
// Sqlite Database
|
||||||
// librariesLocation isn't used because it's too long for replacing paths in native libraries
|
// librariesLocation isn't used because it's too long for replacing paths in native libraries
|
||||||
// Allowing strings larger than the original string would require shifting the entire binary's contents
|
// Allowing strings larger than the original string would require shifting the entire binary's contents
|
||||||
|
relocate "org.sqlite", "dh_sqlite", {
|
||||||
|
exclude "org/sqlite/native/**"
|
||||||
|
}
|
||||||
|
relocate "jdbc:sqlite", "jdbc:dh_sqlite"
|
||||||
|
|
||||||
transform(NativeTransformer) {
|
transform(NativeTransformer) {
|
||||||
rootDir = project.rootDir
|
rootDir = project.rootDir
|
||||||
|
|
||||||
before {
|
|
||||||
relocate "org.sqlite", "dh_sqlite", {
|
|
||||||
exclude "org/sqlite/native/**"
|
|
||||||
}
|
|
||||||
relocate "jdbc:sqlite", "jdbc:dh_sqlite"
|
|
||||||
}
|
|
||||||
|
|
||||||
relocateNative "org/sqlite", "dh_sqlite"
|
relocateNative "org/sqlite", "dh_sqlite"
|
||||||
relocateNative "org_sqlite", "dh_1sqlite"
|
relocateNative "org_sqlite", "dh_1sqlite"
|
||||||
}
|
}
|
||||||
@@ -502,6 +448,8 @@ 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,
|
||||||
|
|
||||||
|
neoforge_version_range : neoforge_version_range,
|
||||||
]
|
]
|
||||||
|
|
||||||
// replace any properties in the sub-projects with the values defined here
|
// replace any properties in the sub-projects with the values defined here
|
||||||
@@ -582,8 +530,9 @@ allprojects { p ->
|
|||||||
apply plugin: "java"
|
apply plugin: "java"
|
||||||
apply plugin: "maven-publish"
|
apply plugin: "maven-publish"
|
||||||
|
|
||||||
|
// Sets the name of the jar, the version will contain the name of the project if it isn't the root project
|
||||||
archivesBaseName = rootProject.mod_name
|
archivesBaseName = rootProject.mod_name
|
||||||
version = project.name + "-" + rootProject.versionStr
|
version = (project == rootProject ? "" : 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
|
||||||
@@ -748,14 +697,3 @@ allprojects { p ->
|
|||||||
withSourcesJar()
|
withSourcesJar()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Delete the merged folder when running clean
|
|
||||||
task cleanMergedJars() {
|
|
||||||
def mergedFolder = file("Merged")
|
|
||||||
if (mergedFolder.exists()) {
|
|
||||||
delete(mergedFolder)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// add cleanMergedJars to the end of the "clean" task
|
|
||||||
tasks["clean"].finalizedBy(cleanMergedJars)
|
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ for d in versionProperties/*; do
|
|||||||
echo "==================== Merging $version ===================="
|
echo "==================== Merging $version ===================="
|
||||||
sh gradlew mergeJars -PmcVer=$version
|
sh gradlew mergeJars -PmcVer=$version
|
||||||
if [ $? != 0 ]; then continue; fi
|
if [ $? != 0 ]; then continue; fi
|
||||||
|
|
||||||
echo "==================== Moving jar ===================="
|
echo "==================== Moving jar ===================="
|
||||||
mv Merged/*.jar buildAllJars/
|
mv build/merged/*.jar buildAllJars/
|
||||||
done
|
done
|
||||||
|
|||||||
+6
-3
@@ -15,12 +15,15 @@ for %%f in (versionProperties\*) do (
|
|||||||
@rem Clean out the folders, build it, and merge it
|
@rem Clean out the folders, build it, and merge it
|
||||||
echo ==================== Cleaning workspace to build !version! ====================
|
echo ==================== Cleaning workspace to build !version! ====================
|
||||||
call .\gradlew.bat clean
|
call .\gradlew.bat clean
|
||||||
echo ==================== Building !version! ====================
|
|
||||||
|
echo ==================== Building !version! ====================
|
||||||
call .\gradlew.bat build -PmcVer="!version!"
|
call .\gradlew.bat build -PmcVer="!version!"
|
||||||
echo ==================== Merging !version! ====================
|
|
||||||
|
echo ==================== Merging !version! ====================
|
||||||
call .\gradlew.bat mergeJars -PmcVer="!version!"
|
call .\gradlew.bat mergeJars -PmcVer="!version!"
|
||||||
|
|
||||||
echo ==================== Moving jar ====================
|
echo ==================== Moving jar ====================
|
||||||
move Merged\*.jar buildAllJars\
|
move build\merged\*.jar buildAllJars\
|
||||||
)
|
)
|
||||||
|
|
||||||
endlocal
|
endlocal
|
||||||
|
|||||||
@@ -12,14 +12,15 @@ class NativeRelocator
|
|||||||
/**
|
/**
|
||||||
* Initializes the NativeRelocator by preparing the environment if necessary.
|
* Initializes the NativeRelocator by preparing the environment if necessary.
|
||||||
* Executes the appropriate preparation script based on the OS.
|
* Executes the appropriate preparation script based on the OS.
|
||||||
*
|
|
||||||
* @throws Exception if the preparation script fails or an unsupported OS is detected.
|
|
||||||
*/
|
*/
|
||||||
NativeRelocator(Path rootDirectory) throws Exception
|
NativeRelocator(Path rootDirectory)
|
||||||
{
|
{
|
||||||
this.rootDirectory = rootDirectory;
|
this.rootDirectory = rootDirectory;
|
||||||
this.cacheRoot = this.rootDirectory.resolve("cache");
|
this.cacheRoot = this.rootDirectory.resolve("cache");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void prepare() throws Exception
|
||||||
|
{
|
||||||
if (this.rootDirectory.resolve(".venv").toFile().exists())
|
if (this.rootDirectory.resolve(".venv").toFile().exists())
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
@@ -33,7 +34,10 @@ class NativeRelocator
|
|||||||
{
|
{
|
||||||
processBuilder.command("powershell", "-ExecutionPolicy", "Bypass", "./prepare.ps1");
|
processBuilder.command("powershell", "-ExecutionPolicy", "Bypass", "./prepare.ps1");
|
||||||
}
|
}
|
||||||
else if (os.contains("nix") || os.contains("nux") || os.contains("mac"))
|
else if (os.contains("nix")
|
||||||
|
|| os.contains("nux")
|
||||||
|
|| os.contains("mac")
|
||||||
|
|| os.contains("freebsd"))
|
||||||
{
|
{
|
||||||
processBuilder.command("./prepare.sh");
|
processBuilder.command("./prepare.sh");
|
||||||
}
|
}
|
||||||
@@ -196,6 +200,9 @@ class NativeRelocator
|
|||||||
return Files.readAllBytes(outputFilePath);
|
return Files.readAllBytes(outputFilePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
System.out.println("Relocating to " + outputPath + "...");
|
||||||
|
this.prepare();
|
||||||
|
|
||||||
for (Map.Entry<String, String> replacement : replacements.entrySet())
|
for (Map.Entry<String, String> replacement : replacements.entrySet())
|
||||||
{
|
{
|
||||||
this.replaceInNullTerminatedStrings(content, replacement.getKey(), replacement.getValue());
|
this.replaceInNullTerminatedStrings(content, replacement.getKey(), replacement.getValue());
|
||||||
|
|||||||
+33
-16
@@ -5,11 +5,12 @@ import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiAfterDh
|
|||||||
import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiBeforeDhInitEvent;
|
import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiBeforeDhInitEvent;
|
||||||
import com.seibel.distanthorizons.common.commands.CommandInitializer;
|
import com.seibel.distanthorizons.common.commands.CommandInitializer;
|
||||||
import com.seibel.distanthorizons.common.wrappers.DependencySetup;
|
import com.seibel.distanthorizons.common.wrappers.DependencySetup;
|
||||||
|
import com.seibel.distanthorizons.common.wrappers.gui.DhDebugScreenEntry;
|
||||||
import com.seibel.distanthorizons.common.wrappers.minecraft.MinecraftServerWrapper;
|
import com.seibel.distanthorizons.common.wrappers.minecraft.MinecraftServerWrapper;
|
||||||
import com.seibel.distanthorizons.core.api.internal.ClientApi;
|
import com.seibel.distanthorizons.core.api.internal.ClientApi;
|
||||||
import com.seibel.distanthorizons.core.api.internal.SharedApi;
|
import com.seibel.distanthorizons.core.api.internal.SharedApi;
|
||||||
import com.seibel.distanthorizons.core.config.Config;
|
import com.seibel.distanthorizons.core.config.Config;
|
||||||
import com.seibel.distanthorizons.core.config.ConfigBase;
|
import com.seibel.distanthorizons.core.config.ConfigHandler;
|
||||||
import com.seibel.distanthorizons.core.config.eventHandlers.presets.ThreadPresetConfigEventHandler;
|
import com.seibel.distanthorizons.core.config.eventHandlers.presets.ThreadPresetConfigEventHandler;
|
||||||
import com.seibel.distanthorizons.core.dependencyInjection.ModAccessorInjector;
|
import com.seibel.distanthorizons.core.dependencyInjection.ModAccessorInjector;
|
||||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||||
@@ -23,7 +24,7 @@ import com.seibel.distanthorizons.coreapi.ModInfo;
|
|||||||
import net.minecraft.commands.CommandSourceStack;
|
import net.minecraft.commands.CommandSourceStack;
|
||||||
import net.minecraft.server.MinecraftServer;
|
import net.minecraft.server.MinecraftServer;
|
||||||
import net.minecraft.server.dedicated.DedicatedServer;
|
import net.minecraft.server.dedicated.DedicatedServer;
|
||||||
import org.apache.logging.log4j.Logger;
|
import com.seibel.distanthorizons.core.logging.DhLogger;
|
||||||
|
|
||||||
import java.lang.invoke.MethodHandles;
|
import java.lang.invoke.MethodHandles;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
@@ -35,7 +36,7 @@ import java.util.function.Supplier;
|
|||||||
*/
|
*/
|
||||||
public abstract class AbstractModInitializer
|
public abstract class AbstractModInitializer
|
||||||
{
|
{
|
||||||
protected static final Logger LOGGER = DhLoggerBuilder.getLogger(MethodHandles.lookup().lookupClass().getSimpleName());
|
protected static final DhLogger LOGGER = new DhLoggerBuilder().build();
|
||||||
|
|
||||||
private CommandInitializer commandInitializer;
|
private CommandInitializer commandInitializer;
|
||||||
|
|
||||||
@@ -45,7 +46,8 @@ public abstract class AbstractModInitializer
|
|||||||
// abstract methods //
|
// abstract methods //
|
||||||
//==================//
|
//==================//
|
||||||
|
|
||||||
protected abstract void createInitialBindings();
|
protected abstract void createInitialSharedBindings();
|
||||||
|
protected abstract void createInitialClientBindings();
|
||||||
protected abstract IEventProxy createClientProxy();
|
protected abstract IEventProxy createClientProxy();
|
||||||
protected abstract IEventProxy createServerProxy(boolean isDedicated);
|
protected abstract IEventProxy createServerProxy(boolean isDedicated);
|
||||||
protected abstract void initializeModCompat();
|
protected abstract void initializeModCompat();
|
||||||
@@ -65,8 +67,9 @@ public abstract class AbstractModInitializer
|
|||||||
public void onInitializeClient()
|
public void onInitializeClient()
|
||||||
{
|
{
|
||||||
DependencySetup.createClientBindings();
|
DependencySetup.createClientBindings();
|
||||||
|
this.createInitialClientBindings();
|
||||||
|
|
||||||
LOGGER.info("Initializing " + ModInfo.READABLE_NAME + " client.");
|
LOGGER.info("Initializing " + ModInfo.READABLE_NAME + " client, firing DhApiBeforeDhInitEvent...");
|
||||||
ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeDhInitEvent.class, null);
|
ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeDhInitEvent.class, null);
|
||||||
|
|
||||||
this.startup();
|
this.startup();
|
||||||
@@ -77,13 +80,18 @@ public abstract class AbstractModInitializer
|
|||||||
|
|
||||||
this.initializeModCompat();
|
this.initializeModCompat();
|
||||||
|
|
||||||
LOGGER.info(ModInfo.READABLE_NAME + " client Initialized.");
|
|
||||||
ApiEventInjector.INSTANCE.fireAllEvents(DhApiAfterDhInitEvent.class, null);
|
|
||||||
|
|
||||||
// Client uses config for auto-updater, so it's initialized here instead of post-init stage
|
// Client uses config for auto-updater, so it's initialized here instead of post-init stage
|
||||||
this.initConfig();
|
this.initConfig();
|
||||||
logModIncompatibilityWarnings(); // needs to be called after config loading
|
logModIncompatibilityWarnings(); // needs to be called after config loading
|
||||||
|
|
||||||
|
LOGGER.info(ModInfo.READABLE_NAME + " client Initialized.");
|
||||||
|
|
||||||
|
#if MC_VER < MC_1_21_9
|
||||||
|
// debug screen rendering handled via a mixin
|
||||||
|
#else
|
||||||
|
DhDebugScreenEntry.register();
|
||||||
|
#endif
|
||||||
|
|
||||||
this.subscribeClientStartedEvent(this::postInit);
|
this.subscribeClientStartedEvent(this::postInit);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -91,7 +99,7 @@ public abstract class AbstractModInitializer
|
|||||||
{
|
{
|
||||||
DependencySetup.createServerBindings();
|
DependencySetup.createServerBindings();
|
||||||
|
|
||||||
LOGGER.info("Initializing " + ModInfo.READABLE_NAME + " server.");
|
LOGGER.info("Initializing " + ModInfo.READABLE_NAME + " server, firing DhApiBeforeDhInitEvent event...");
|
||||||
ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeDhInitEvent.class, null);
|
ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeDhInitEvent.class, null);
|
||||||
|
|
||||||
this.startup();
|
this.startup();
|
||||||
@@ -106,8 +114,7 @@ public abstract class AbstractModInitializer
|
|||||||
|
|
||||||
this.initializeModCompat();
|
this.initializeModCompat();
|
||||||
|
|
||||||
LOGGER.info(ModInfo.READABLE_NAME + " server Initialized.");
|
LOGGER.info(ModInfo.READABLE_NAME + " server Initialized, adding event subscribers...");
|
||||||
ApiEventInjector.INSTANCE.fireAllEvents(DhApiAfterDhInitEvent.class, null);
|
|
||||||
|
|
||||||
this.subscribeRegisterCommandsEvent(dispatcher -> { this.commandInitializer = new CommandInitializer(dispatcher); });
|
this.subscribeRegisterCommandsEvent(dispatcher -> { this.commandInitializer = new CommandInitializer(dispatcher); });
|
||||||
|
|
||||||
@@ -121,7 +128,7 @@ public abstract class AbstractModInitializer
|
|||||||
|
|
||||||
this.checkForUpdates();
|
this.checkForUpdates();
|
||||||
|
|
||||||
LOGGER.info("Dedicated server initialized at " + server.getServerDirectory());
|
LOGGER.info(ModInfo.READABLE_NAME + " server Initialized at " + server.getServerDirectory());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -135,7 +142,7 @@ public abstract class AbstractModInitializer
|
|||||||
{
|
{
|
||||||
DependencySetup.createSharedBindings();
|
DependencySetup.createSharedBindings();
|
||||||
SharedApi.init();
|
SharedApi.init();
|
||||||
this.createInitialBindings();
|
this.createInitialSharedBindings();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void logBuildInfo()
|
private void logBuildInfo()
|
||||||
@@ -163,8 +170,9 @@ public abstract class AbstractModInitializer
|
|||||||
|
|
||||||
private void initConfig()
|
private void initConfig()
|
||||||
{
|
{
|
||||||
ConfigBase.INSTANCE = new ConfigBase(ModInfo.ID, ModInfo.NAME, Config.class, ModInfo.CONFIG_FILE_VERSION);
|
ConfigHandler.tryRunFirstTimeSetup();
|
||||||
Config.completeDelayedSetup();
|
Config.completeDelayedSetup();
|
||||||
|
DhLogger.runDelayedConfigSetup();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkForUpdates()
|
private void checkForUpdates()
|
||||||
@@ -183,9 +191,18 @@ public abstract class AbstractModInitializer
|
|||||||
|
|
||||||
private void postInit()
|
private void postInit()
|
||||||
{
|
{
|
||||||
LOGGER.info("Post-Initializing Mod");
|
LOGGER.info("Running Delayed setup...");
|
||||||
this.runDelayedSetup();
|
this.runDelayedSetup();
|
||||||
LOGGER.info("Mod Post-Initialized");
|
|
||||||
|
if (ConfigHandler.INSTANCE == null)
|
||||||
|
{
|
||||||
|
throw new IllegalStateException("Config was not initialized. Make sure to call LodCommonMain.initConfig() before calling this method.");
|
||||||
|
}
|
||||||
|
|
||||||
|
LOGGER.info("Delayed setup complete, firing DhApiAfterDhInitEvent event...");
|
||||||
|
|
||||||
|
// should be fired after all delayed setup so singletons and config can be accessed
|
||||||
|
ApiEventInjector.INSTANCE.fireAllEvents(DhApiAfterDhInitEvent.class, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+27
-8
@@ -1,7 +1,8 @@
|
|||||||
package com.seibel.distanthorizons.common;
|
package com.seibel.distanthorizons.common;
|
||||||
|
|
||||||
import com.seibel.distanthorizons.core.config.Config;
|
import com.seibel.distanthorizons.core.config.Config;
|
||||||
import com.seibel.distanthorizons.core.logging.ConfigBasedLogger;
|
import com.seibel.distanthorizons.core.logging.DhLogger;
|
||||||
|
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||||
import com.seibel.distanthorizons.core.network.event.internal.IncompatibleMessageInternalEvent;
|
import com.seibel.distanthorizons.core.network.event.internal.IncompatibleMessageInternalEvent;
|
||||||
import com.seibel.distanthorizons.core.network.event.internal.ProtocolErrorInternalEvent;
|
import com.seibel.distanthorizons.core.network.event.internal.ProtocolErrorInternalEvent;
|
||||||
import com.seibel.distanthorizons.core.network.messages.MessageRegistry;
|
import com.seibel.distanthorizons.core.network.messages.MessageRegistry;
|
||||||
@@ -14,15 +15,15 @@ import io.netty.buffer.ByteBufUtil;
|
|||||||
import net.minecraft.network.FriendlyByteBuf;
|
import net.minecraft.network.FriendlyByteBuf;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
import net.minecraft.server.level.ServerPlayer;
|
import net.minecraft.server.level.ServerPlayer;
|
||||||
import org.apache.logging.log4j.LogManager;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
public abstract class AbstractPluginPacketSender implements IPluginPacketSender
|
public abstract class AbstractPluginPacketSender implements IPluginPacketSender
|
||||||
{
|
{
|
||||||
private static final ConfigBasedLogger LOGGER = new ConfigBasedLogger(LogManager.getLogger(),
|
private static final DhLogger LOGGER = new DhLoggerBuilder()
|
||||||
() -> Config.Common.Logging.logNetworkEvent.get());
|
.fileLevelConfig(Config.Common.Logging.logNetworkEventToFile)
|
||||||
|
.build();
|
||||||
|
|
||||||
#if MC_VER >= MC_1_21_1
|
#if MC_VER >= MC_1_21_1
|
||||||
public static final ResourceLocation WRAPPER_PACKET_RESOURCE = ResourceLocation.fromNamespaceAndPath(ModInfo.RESOURCE_NAMESPACE, ModInfo.WRAPPER_PACKET_PATH);
|
public static final ResourceLocation WRAPPER_PACKET_RESOURCE = ResourceLocation.fromNamespaceAndPath(ModInfo.RESOURCE_NAMESPACE, ModInfo.WRAPPER_PACKET_PATH);
|
||||||
@@ -30,6 +31,16 @@ public abstract class AbstractPluginPacketSender implements IPluginPacketSender
|
|||||||
public static final ResourceLocation WRAPPER_PACKET_RESOURCE = new ResourceLocation(ModInfo.RESOURCE_NAMESPACE, ModInfo.WRAPPER_PACKET_PATH);
|
public static final ResourceLocation WRAPPER_PACKET_RESOURCE = new ResourceLocation(ModInfo.RESOURCE_NAMESPACE, ModInfo.WRAPPER_PACKET_PATH);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// "Forge byte" is an unused packet ID. We have our own system which works with all mod loaders,
|
||||||
|
// so we're just accounting for it by reading the protocol version as a byte instead of a short in Forge, to keep cross-loader compatibility
|
||||||
|
private final boolean forgeByteInProtocolVersion;
|
||||||
|
|
||||||
|
|
||||||
|
public AbstractPluginPacketSender() { this(false); }
|
||||||
|
public AbstractPluginPacketSender(boolean forgeByteInProtocolVersion)
|
||||||
|
{
|
||||||
|
this.forgeByteInProtocolVersion = forgeByteInProtocolVersion;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final void sendToClient(IServerPlayerWrapper serverPlayer, AbstractNetworkMessage message)
|
public final void sendToClient(IServerPlayerWrapper serverPlayer, AbstractNetworkMessage message)
|
||||||
@@ -41,7 +52,7 @@ public abstract class AbstractPluginPacketSender implements IPluginPacketSender
|
|||||||
@Override
|
@Override
|
||||||
public abstract void sendToServer(AbstractNetworkMessage message);
|
public abstract void sendToServer(AbstractNetworkMessage message);
|
||||||
|
|
||||||
public static AbstractNetworkMessage decodeMessage(FriendlyByteBuf in)
|
public AbstractNetworkMessage decodeMessage(FriendlyByteBuf in)
|
||||||
{
|
{
|
||||||
AbstractNetworkMessage message = null;
|
AbstractNetworkMessage message = null;
|
||||||
|
|
||||||
@@ -49,7 +60,7 @@ public abstract class AbstractPluginPacketSender implements IPluginPacketSender
|
|||||||
{
|
{
|
||||||
in.markReaderIndex();
|
in.markReaderIndex();
|
||||||
|
|
||||||
int protocolVersion = in.readShort();
|
int protocolVersion = this.forgeByteInProtocolVersion ? in.readByte() : in.readShort();
|
||||||
if (protocolVersion != ModInfo.PROTOCOL_VERSION)
|
if (protocolVersion != ModInfo.PROTOCOL_VERSION)
|
||||||
{
|
{
|
||||||
return new IncompatibleMessageInternalEvent(protocolVersion);
|
return new IncompatibleMessageInternalEvent(protocolVersion);
|
||||||
@@ -82,11 +93,19 @@ public abstract class AbstractPluginPacketSender implements IPluginPacketSender
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void encodeMessage(FriendlyByteBuf out, AbstractNetworkMessage message)
|
public void encodeMessage(FriendlyByteBuf out, AbstractNetworkMessage message)
|
||||||
{
|
{
|
||||||
// This is intentionally unhandled, because errors related to this are unlikely to appear in wild
|
// This is intentionally unhandled, because errors related to this are unlikely to appear in wild
|
||||||
Objects.requireNonNull(message);
|
Objects.requireNonNull(message);
|
||||||
out.writeShort(ModInfo.PROTOCOL_VERSION);
|
|
||||||
|
if (this.forgeByteInProtocolVersion)
|
||||||
|
{
|
||||||
|
out.writeByte(ModInfo.PROTOCOL_VERSION);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
out.writeShort(ModInfo.PROTOCOL_VERSION);
|
||||||
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -2,7 +2,9 @@ package com.seibel.distanthorizons.common;
|
|||||||
|
|
||||||
#if MC_VER >= MC_1_20_6
|
#if MC_VER >= MC_1_20_6
|
||||||
|
|
||||||
|
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||||
import com.seibel.distanthorizons.core.network.messages.AbstractNetworkMessage;
|
import com.seibel.distanthorizons.core.network.messages.AbstractNetworkMessage;
|
||||||
|
import com.seibel.distanthorizons.core.wrapperInterfaces.misc.IPluginPacketSender;
|
||||||
import net.minecraft.network.FriendlyByteBuf;
|
import net.minecraft.network.FriendlyByteBuf;
|
||||||
import net.minecraft.network.codec.StreamCodec;
|
import net.minecraft.network.codec.StreamCodec;
|
||||||
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
|
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
|
||||||
@@ -12,6 +14,7 @@ import org.jetbrains.annotations.Nullable;
|
|||||||
public record CommonPacketPayload(@Nullable AbstractNetworkMessage message) implements CustomPacketPayload
|
public record CommonPacketPayload(@Nullable AbstractNetworkMessage message) implements CustomPacketPayload
|
||||||
{
|
{
|
||||||
public static final Type<CommonPacketPayload> TYPE = new Type<>(AbstractPluginPacketSender.WRAPPER_PACKET_RESOURCE);
|
public static final Type<CommonPacketPayload> TYPE = new Type<>(AbstractPluginPacketSender.WRAPPER_PACKET_RESOURCE);
|
||||||
|
private static final AbstractPluginPacketSender PACKET_SENDER = (AbstractPluginPacketSender) SingletonInjector.INSTANCE.get(IPluginPacketSender.class);
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
@@ -23,11 +26,11 @@ public record CommonPacketPayload(@Nullable AbstractNetworkMessage message) impl
|
|||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public CommonPacketPayload decode(@NotNull FriendlyByteBuf in)
|
public CommonPacketPayload decode(@NotNull FriendlyByteBuf in)
|
||||||
{ return new CommonPacketPayload(AbstractPluginPacketSender.decodeMessage(in)); }
|
{ return new CommonPacketPayload(PACKET_SENDER.decodeMessage(in)); }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void encode(@NotNull FriendlyByteBuf out, CommonPacketPayload payload)
|
public void encode(@NotNull FriendlyByteBuf out, CommonPacketPayload payload)
|
||||||
{ AbstractPluginPacketSender.encodeMessage(out, payload.message()); }
|
{ PACKET_SENDER.encodeMessage(out, payload.message()); }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,8 +3,8 @@ package com.seibel.distanthorizons.common.commands;
|
|||||||
import com.mojang.brigadier.arguments.*;
|
import com.mojang.brigadier.arguments.*;
|
||||||
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
|
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
|
||||||
import com.mojang.brigadier.context.CommandContext;
|
import com.mojang.brigadier.context.CommandContext;
|
||||||
import com.seibel.distanthorizons.core.config.ConfigBase;
|
import com.seibel.distanthorizons.core.config.ConfigHandler;
|
||||||
import com.seibel.distanthorizons.core.config.types.AbstractConfigType;
|
import com.seibel.distanthorizons.core.config.types.AbstractConfigBase;
|
||||||
import com.seibel.distanthorizons.core.config.types.ConfigEntry;
|
import com.seibel.distanthorizons.core.config.types.ConfigEntry;
|
||||||
import net.minecraft.commands.CommandSourceStack;
|
import net.minecraft.commands.CommandSourceStack;
|
||||||
|
|
||||||
@@ -43,7 +43,7 @@ public class ConfigCommand extends AbstractCommand
|
|||||||
LiteralArgumentBuilder<CommandSourceStack> builder = literal("config");
|
LiteralArgumentBuilder<CommandSourceStack> builder = literal("config");
|
||||||
HashSet<String> addedCommands = new HashSet<>();
|
HashSet<String> addedCommands = new HashSet<>();
|
||||||
|
|
||||||
for (AbstractConfigType<?, ?> type : ConfigBase.INSTANCE.entries)
|
for (AbstractConfigBase<?> type : ConfigHandler.INSTANCE.configBaseList)
|
||||||
{
|
{
|
||||||
// Skip non-config entries
|
// Skip non-config entries
|
||||||
if (!(type instanceof ConfigEntry))
|
if (!(type instanceof ConfigEntry))
|
||||||
|
|||||||
@@ -17,9 +17,9 @@ public class CrashCommand extends AbstractCommand
|
|||||||
.requires(this::isPlayerSource)
|
.requires(this::isPlayerSource)
|
||||||
.then(literal("encode")
|
.then(literal("encode")
|
||||||
.executes(c -> {
|
.executes(c -> {
|
||||||
assert SharedApi.getIDhServerWorld() != null;
|
assert SharedApi.tryGetDhServerWorld() != null;
|
||||||
|
|
||||||
ServerPlayerState serverPlayerState = SharedApi.getIDhServerWorld().getServerPlayerStateManager()
|
ServerPlayerState serverPlayerState = SharedApi.tryGetDhServerWorld().getServerPlayerStateManager()
|
||||||
.getConnectedPlayer(this.getSourcePlayer(c));
|
.getConnectedPlayer(this.getSourcePlayer(c));
|
||||||
if (serverPlayerState != null)
|
if (serverPlayerState != null)
|
||||||
{
|
{
|
||||||
@@ -29,9 +29,9 @@ public class CrashCommand extends AbstractCommand
|
|||||||
}))
|
}))
|
||||||
.then(literal("decode")
|
.then(literal("decode")
|
||||||
.executes(c -> {
|
.executes(c -> {
|
||||||
assert SharedApi.getIDhServerWorld() != null;
|
assert SharedApi.tryGetDhServerWorld() != null;
|
||||||
|
|
||||||
ServerPlayerState serverPlayerState = SharedApi.getIDhServerWorld().getServerPlayerStateManager()
|
ServerPlayerState serverPlayerState = SharedApi.tryGetDhServerWorld().getServerPlayerStateManager()
|
||||||
.getConnectedPlayer(this.getSourcePlayer(c));
|
.getConnectedPlayer(this.getSourcePlayer(c));
|
||||||
if (serverPlayerState != null)
|
if (serverPlayerState != null)
|
||||||
{
|
{
|
||||||
|
|||||||
+1
-5
@@ -59,13 +59,9 @@ public class DependencySetup
|
|||||||
DependencySetupDoneCheck.isDone = true;
|
DependencySetupDoneCheck.isDone = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//@Environment(EnvType.SERVER)
|
|
||||||
public static void createServerBindings()
|
public static void createServerBindings()
|
||||||
{
|
{ SingletonInjector.INSTANCE.bind(IMinecraftSharedWrapper.class, MinecraftServerWrapper.INSTANCE); }
|
||||||
SingletonInjector.INSTANCE.bind(IMinecraftSharedWrapper.class, MinecraftServerWrapper.INSTANCE);
|
|
||||||
}
|
|
||||||
|
|
||||||
//@Environment(EnvType.CLIENT)
|
|
||||||
public static void createClientBindings()
|
public static void createClientBindings()
|
||||||
{
|
{
|
||||||
SingletonInjector.INSTANCE.bind(IMinecraftClientWrapper.class, MinecraftClientWrapper.INSTANCE);
|
SingletonInjector.INSTANCE.bind(IMinecraftClientWrapper.class, MinecraftClientWrapper.INSTANCE);
|
||||||
|
|||||||
+6
-2
@@ -49,7 +49,9 @@ public class McObjectConverter
|
|||||||
@Deprecated
|
@Deprecated
|
||||||
public static Mat4f Convert(
|
public static Mat4f Convert(
|
||||||
#if MC_VER < MC_1_19_4 com.mojang.math.Matrix4f
|
#if MC_VER < MC_1_19_4 com.mojang.math.Matrix4f
|
||||||
#else org.joml.Matrix4f #endif
|
#elif MC_VER < MC_1_21_6 org.joml.Matrix4f
|
||||||
|
#else org.joml.Matrix4fc
|
||||||
|
#endif
|
||||||
mcMatrix)
|
mcMatrix)
|
||||||
{
|
{
|
||||||
FloatBuffer buffer = FloatBuffer.allocate(16);
|
FloatBuffer buffer = FloatBuffer.allocate(16);
|
||||||
@@ -63,7 +65,9 @@ public class McObjectConverter
|
|||||||
/** Taken from Minecraft's com.mojang.math.Matrix4f class from 1.18.2 */
|
/** Taken from Minecraft's com.mojang.math.Matrix4f class from 1.18.2 */
|
||||||
private static void storeMatrix(
|
private static void storeMatrix(
|
||||||
#if MC_VER < MC_1_19_4 com.mojang.math.Matrix4f
|
#if MC_VER < MC_1_19_4 com.mojang.math.Matrix4f
|
||||||
#else org.joml.Matrix4f #endif
|
#elif MC_VER < MC_1_21_6 org.joml.Matrix4f
|
||||||
|
#else org.joml.Matrix4fc
|
||||||
|
#endif
|
||||||
matrix,
|
matrix,
|
||||||
FloatBuffer buffer)
|
FloatBuffer buffer)
|
||||||
{
|
{
|
||||||
|
|||||||
+12
-1
@@ -71,7 +71,18 @@ public class VersionConstants implements IVersionConstants
|
|||||||
#elif MC_VER == MC_1_21_3
|
#elif MC_VER == MC_1_21_3
|
||||||
return "1.21.3";
|
return "1.21.3";
|
||||||
#elif MC_VER == MC_1_21_4
|
#elif MC_VER == MC_1_21_4
|
||||||
return "1.21_4";
|
return "1.21.4";
|
||||||
|
#elif MC_VER == MC_1_21_5
|
||||||
|
return "1.21.5";
|
||||||
|
#elif MC_VER == MC_1_21_6
|
||||||
|
return "1.21.6";
|
||||||
|
#elif MC_VER == MC_1_21_8
|
||||||
|
return "1.21.8";
|
||||||
|
|
||||||
|
#elif MC_VER == MC_1_21_9
|
||||||
|
return "1.21.9";
|
||||||
|
#elif MC_VER == MC_1_21_10
|
||||||
|
return "1.21.10";
|
||||||
#else
|
#else
|
||||||
ERROR MC version constant missing
|
ERROR MC version constant missing
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+335
@@ -0,0 +1,335 @@
|
|||||||
|
package com.seibel.distanthorizons.common.wrappers.block;
|
||||||
|
|
||||||
|
import com.seibel.distanthorizons.core.config.Config;
|
||||||
|
import com.seibel.distanthorizons.core.dataObjects.BlockBiomeWrapperPair;
|
||||||
|
import com.seibel.distanthorizons.core.dataObjects.fullData.sources.FullDataSourceV2;
|
||||||
|
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||||
|
import com.seibel.distanthorizons.core.pos.DhSectionPos;
|
||||||
|
import com.seibel.distanthorizons.core.pos.blockPos.DhBlockPosMutable;
|
||||||
|
import com.seibel.distanthorizons.core.util.ColorUtil;
|
||||||
|
import com.seibel.distanthorizons.core.util.FullDataPointUtil;
|
||||||
|
|
||||||
|
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
|
||||||
|
import it.unimi.dsi.fastutil.longs.LongArrayList;
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.client.multiplayer.ClientLevel;
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.world.level.BlockAndTintGetter;
|
||||||
|
import net.minecraft.world.level.ColorResolver;
|
||||||
|
import net.minecraft.world.level.biome.Biome;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
import com.seibel.distanthorizons.core.logging.DhLogger;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
#if MC_VER >= MC_1_18_2
|
||||||
|
import net.minecraft.core.Holder;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
public abstract class AbstractDhTintGetter implements BlockAndTintGetter
|
||||||
|
{
|
||||||
|
private static final DhLogger LOGGER = new DhLoggerBuilder().build();
|
||||||
|
|
||||||
|
#if MC_VER < MC_1_18_2
|
||||||
|
private static final ConcurrentHashMap<String, Biome> BIOME_BY_RESOURCE_STRING = new ConcurrentHashMap<>();
|
||||||
|
#else
|
||||||
|
private static final ConcurrentHashMap<String, Holder<Biome>> BIOME_BY_RESOURCE_STRING = new ConcurrentHashMap<>();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
private static final ConcurrentHashMap<BlockBiomeWrapperPair, Integer> COLOR_BY_BLOCK_BIOME_PAIR = new ConcurrentHashMap<>();
|
||||||
|
/** returned if the color cache is incomplete */
|
||||||
|
public static final int INVALID_COLOR = Integer.MIN_VALUE;
|
||||||
|
|
||||||
|
|
||||||
|
protected BiomeWrapper biomeWrapper;
|
||||||
|
protected BlockStateWrapper blockStateWrapper;
|
||||||
|
protected FullDataSourceV2 fullDataSource;
|
||||||
|
protected int smoothingRadiusInBlocks;
|
||||||
|
protected IClientLevelWrapper clientLevelWrapper;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//=============//
|
||||||
|
// constructor //
|
||||||
|
//=============//
|
||||||
|
|
||||||
|
public AbstractDhTintGetter() { }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mutates this getter so we can access the necessary
|
||||||
|
* variables for tint getting.
|
||||||
|
*/
|
||||||
|
public void update(BiomeWrapper biomeWrapper, BlockStateWrapper blockStateWrapper, FullDataSourceV2 fullDataSource, IClientLevelWrapper clientLevelWrapper)
|
||||||
|
{
|
||||||
|
this.biomeWrapper = biomeWrapper;
|
||||||
|
this.blockStateWrapper = blockStateWrapper;
|
||||||
|
this.fullDataSource = fullDataSource;
|
||||||
|
this.clientLevelWrapper = clientLevelWrapper;
|
||||||
|
this.smoothingRadiusInBlocks = Config.Client.Advanced.Graphics.Quality.lodBiomeBlending.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//================//
|
||||||
|
// shared methods //
|
||||||
|
//================//
|
||||||
|
|
||||||
|
/** Called by MC's tint getter */
|
||||||
|
@Override
|
||||||
|
public int getBlockTint(@NotNull BlockPos blockPos, @NotNull ColorResolver colorResolver)
|
||||||
|
{
|
||||||
|
DhBlockPosMutable mutableBlockPos = new DhBlockPosMutable(blockPos.getX(), blockPos.getY(), blockPos.getZ());
|
||||||
|
return this.tryGetBlockTint(mutableBlockPos, colorResolver);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Can be called by DH directly, skipping some of MC's logic
|
||||||
|
* to speed up tint getting slightly.
|
||||||
|
*
|
||||||
|
* @return {@link AbstractDhTintGetter#INVALID_COLOR} if any of the biomes needed for this position
|
||||||
|
* were not cached. In that case calling {@link AbstractDhTintGetter#getBlockTint(BlockPos, ColorResolver)}
|
||||||
|
* will need to be called by MC's ColorResolver so we can
|
||||||
|
* populate the color cache.
|
||||||
|
*/
|
||||||
|
public int tryGetBlockTint(DhBlockPosMutable mutableBlockPos)
|
||||||
|
{ return this.tryGetBlockTint(mutableBlockPos, null); }
|
||||||
|
|
||||||
|
private int tryGetBlockTint(DhBlockPosMutable mutableBlockPos, @Nullable ColorResolver colorResolver)
|
||||||
|
{
|
||||||
|
// determine how wide this data source is so we can determine
|
||||||
|
// if blending should be used
|
||||||
|
byte dataSourceDetailLevel = DhSectionPos.getDetailLevel(this.fullDataSource.getPos());
|
||||||
|
// convert from section detail level to absolute detail level
|
||||||
|
dataSourceDetailLevel = (byte)(dataSourceDetailLevel - DhSectionPos.SECTION_MINIMUM_DETAIL_LEVEL);
|
||||||
|
int dataSourceLodWidthInBlocks = DhSectionPos.getDetailLevelWidthInBlocks(dataSourceDetailLevel);
|
||||||
|
|
||||||
|
// don't do any smoothing if smoothing is disabled or if the LOD
|
||||||
|
// is to large for block-based smoothing to show up
|
||||||
|
if (this.smoothingRadiusInBlocks == 0
|
||||||
|
|| dataSourceLodWidthInBlocks > this.smoothingRadiusInBlocks)
|
||||||
|
{
|
||||||
|
return this.tryGetClientBiomeColor(colorResolver, this.biomeWrapper);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// use a rolling average to calculate the color
|
||||||
|
int dataPointCount = 0;
|
||||||
|
int rollingRed = 0;
|
||||||
|
int rollingGreen = 0;
|
||||||
|
int rollingBlue = 0;
|
||||||
|
|
||||||
|
int xMin = mutableBlockPos.getX() - this.smoothingRadiusInBlocks;
|
||||||
|
int xMax = mutableBlockPos.getX() + this.smoothingRadiusInBlocks;
|
||||||
|
|
||||||
|
int zMin = mutableBlockPos.getZ() - this.smoothingRadiusInBlocks;
|
||||||
|
int zMax = mutableBlockPos.getZ() + this.smoothingRadiusInBlocks;
|
||||||
|
|
||||||
|
|
||||||
|
for (int x = xMin; x < xMax; x++)
|
||||||
|
{
|
||||||
|
for (int z = zMin; z < zMax; z++)
|
||||||
|
{
|
||||||
|
mutableBlockPos.setX(x);
|
||||||
|
mutableBlockPos.setZ(z);
|
||||||
|
|
||||||
|
// this can return the same position/datapoint for larger LODs duplicating work,
|
||||||
|
// however for small smoothing ranges that isn't a big deal and for large LODs
|
||||||
|
// we ignore smoothing anyway
|
||||||
|
long dataPoint = this.fullDataSource.getDataPointAtBlockPos(mutableBlockPos);
|
||||||
|
if (dataPoint == FullDataPointUtil.EMPTY_DATA_POINT)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get the color for this nearby position
|
||||||
|
int id = FullDataPointUtil.getId(dataPoint);
|
||||||
|
BiomeWrapper biomeWrapper = (BiomeWrapper) this.fullDataSource.mapping.getBiomeWrapper(id);
|
||||||
|
int color = this.tryGetClientBiomeColor(colorResolver, biomeWrapper);
|
||||||
|
if (color == INVALID_COLOR)
|
||||||
|
{
|
||||||
|
return INVALID_COLOR;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// rolling average
|
||||||
|
rollingRed += ColorUtil.getRed(color);
|
||||||
|
rollingGreen += ColorUtil.getGreen(color);
|
||||||
|
rollingBlue += ColorUtil.getBlue(color);
|
||||||
|
|
||||||
|
dataPointCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// if no data was present (rarely possible)
|
||||||
|
// just use the default center's color
|
||||||
|
if (dataPointCount == 0)
|
||||||
|
{
|
||||||
|
return this.tryGetClientBiomeColor(colorResolver, this.biomeWrapper);
|
||||||
|
}
|
||||||
|
|
||||||
|
int colorInt = ColorUtil.argbToInt(
|
||||||
|
255, // blending often ignores alpha, having it always 255 prevents multiplication issues later
|
||||||
|
rollingRed / dataPointCount,
|
||||||
|
rollingGreen / dataPointCount,
|
||||||
|
rollingBlue / dataPointCount);
|
||||||
|
return colorInt;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If given a ColorResolver this will always succeed. <Br>
|
||||||
|
* If not it will attempt to use the cached color.
|
||||||
|
*/
|
||||||
|
private int tryGetClientBiomeColor(@Nullable ColorResolver colorResolver, BiomeWrapper biomeWrapper)
|
||||||
|
{
|
||||||
|
BlockBiomeWrapperPair pair = BlockBiomeWrapperPair.get(this.blockStateWrapper, biomeWrapper);
|
||||||
|
|
||||||
|
// use the cached color if possible
|
||||||
|
Integer cachedColor = COLOR_BY_BLOCK_BIOME_PAIR.get(pair); // explicit Integer return here reduces unnecessary allocations
|
||||||
|
if (cachedColor != null)
|
||||||
|
{
|
||||||
|
return cachedColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (colorResolver == null)
|
||||||
|
{
|
||||||
|
// no color resolver is present,
|
||||||
|
// the cache needs to be populated before
|
||||||
|
// we can use the fast path
|
||||||
|
return INVALID_COLOR;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int color = colorResolver.getColor(unwrapClientBiome(biomeWrapper), 0, 0);
|
||||||
|
COLOR_BY_BLOCK_BIOME_PAIR.put(pair, color);
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static Biome unwrapClientBiome(BiomeWrapper biomeWrapper)
|
||||||
|
{
|
||||||
|
String biomeString = biomeWrapper.getSerialString();
|
||||||
|
if (biomeString == null
|
||||||
|
|| biomeString.isEmpty()
|
||||||
|
|| biomeString.equals(BiomeWrapper.EMPTY_BIOME_STRING))
|
||||||
|
{
|
||||||
|
// default to "plains" for empty/invalid biomes
|
||||||
|
biomeString = "minecraft:plains";
|
||||||
|
}
|
||||||
|
|
||||||
|
return unwrapBiome(getClientBiome(biomeString));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static Biome unwrapBiome(#if MC_VER >= MC_1_18_2 Holder<Biome> #else Biome #endif biome)
|
||||||
|
{
|
||||||
|
#if MC_VER >= MC_1_18_2
|
||||||
|
return biome.value();
|
||||||
|
#else
|
||||||
|
return biome;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>Previously, this class might have immediately unwrapped the Holder like this:</p>
|
||||||
|
* <pre>{@code
|
||||||
|
* // Inside constructor (OLD WAY - PROBLEMATIC):
|
||||||
|
* Holder<Biome> biomeHolder = getTheHolderFromSomewhere();
|
||||||
|
* this.biome = biomeHolder.value(); // <-- PROBLEM HERE
|
||||||
|
* }</pre>
|
||||||
|
*
|
||||||
|
* <p>This approach is problematic because the {@link net.minecraft.core.Holder} system,
|
||||||
|
* particularly {@code Holder.Reference}, is designed for <strong>late binding</strong>. Here's why storing
|
||||||
|
* the Holder itself is now necessary:</p>
|
||||||
|
* <ol>
|
||||||
|
* <li>A {@code Holder.Reference<Biome>} might be created initially just with a
|
||||||
|
* {@link net.minecraft.resources.ResourceKey} (like {@code minecraft:plains}), but its actual
|
||||||
|
* {@link net.minecraft.core.Holder#value() value()} (the {@code Biome} object itself) might be {@code null}
|
||||||
|
* at construction time.</li>
|
||||||
|
* <li>Later, during game loading, registry population, or potentially due to modifications by other mods
|
||||||
|
* (e.g., Polytone), the system calls internal binding methods (like {@code bindValue(Biome)})
|
||||||
|
* on the {@code Holder} instance. This sets or <strong>updates</strong> the internal reference to the
|
||||||
|
* actual {@code Biome} object.</li>
|
||||||
|
* <li>Crucially, the binding process might assign a completely <strong>new</strong> {@code Biome} object
|
||||||
|
* instance to the {@code Holder} reference, replacing any previous one.</li>
|
||||||
|
* </ol>
|
||||||
|
*
|
||||||
|
* <p>If we unwrapped the {@code Holder} using {@code .value()} within the constructor (the old way),
|
||||||
|
* our class's internal {@code biome} field would permanently store a reference to whatever {@code Biome}
|
||||||
|
* object the {@code Holder} pointed to *at that exact moment*. It would have no link back to the
|
||||||
|
* {@code Holder} and would be unaware if the {@code Holder} was later updated to point to a different
|
||||||
|
* (or the initially missing) {@code Biome} object. This would lead to using stale or even {@code null} data.</p>
|
||||||
|
*
|
||||||
|
* <p>By storing the {@code Holder<Biome>} itself, this class can call {@link net.minecraft.core.Holder#value()}
|
||||||
|
* whenever the biome information is needed, ensuring it always retrieves the most current {@code Biome}
|
||||||
|
* instance associated with the holder at that time.</p>
|
||||||
|
*/
|
||||||
|
private static #if MC_VER < MC_1_18_2 Biome #else Holder<Biome> #endif getClientBiome(String biomeResourceString)
|
||||||
|
{
|
||||||
|
#if MC_VER < MC_1_18_2
|
||||||
|
Biome biome;
|
||||||
|
#else
|
||||||
|
Holder<Biome> biome;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// calling get instead of compute is slightly faster for already
|
||||||
|
// computed values
|
||||||
|
biome = BIOME_BY_RESOURCE_STRING.get(biomeResourceString);
|
||||||
|
if (biome != null)
|
||||||
|
{
|
||||||
|
return biome;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// cache the client biomes so we don't have to re-parse the resource location every time
|
||||||
|
return BIOME_BY_RESOURCE_STRING.compute(biomeResourceString,
|
||||||
|
(resourceString, existingBiome) ->
|
||||||
|
{
|
||||||
|
if (existingBiome != null)
|
||||||
|
{
|
||||||
|
return existingBiome;
|
||||||
|
}
|
||||||
|
|
||||||
|
ClientLevel clientLevel = Minecraft.getInstance().level;
|
||||||
|
if (clientLevel == null)
|
||||||
|
{
|
||||||
|
// shouldn't happen, but just in case
|
||||||
|
throw new IllegalStateException("Attempted to get client biome when no client level was loaded.");
|
||||||
|
}
|
||||||
|
|
||||||
|
BiomeWrapper.BiomeDeserializeResult result;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
result = BiomeWrapper.deserializeBiome(resourceString, clientLevel.registryAccess());
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
LOGGER.warn("Unable to deserialize client biome ["+resourceString+"], using fallback...");
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
result = BiomeWrapper.deserializeBiome(BiomeWrapper.PLAINS_RESOURCE_LOCATION_STRING, clientLevel.registryAccess());
|
||||||
|
}
|
||||||
|
catch (IOException ex)
|
||||||
|
{
|
||||||
|
// should never happen, if it does this log will explode, but just in case
|
||||||
|
LOGGER.error("Unable to deserialize fallback client biome ["+BiomeWrapper.PLAINS_RESOURCE_LOCATION_STRING+"], returning NULL.");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result.success)
|
||||||
|
{
|
||||||
|
existingBiome = result.biome;
|
||||||
|
}
|
||||||
|
|
||||||
|
return existingBiome;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
+89
-64
@@ -26,10 +26,11 @@ import java.util.Optional;
|
|||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.ConcurrentMap;
|
import java.util.concurrent.ConcurrentMap;
|
||||||
|
|
||||||
|
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper;
|
||||||
import net.minecraft.world.level.Level;
|
import net.minecraft.world.level.Level;
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import com.seibel.distanthorizons.core.logging.DhLogger;
|
||||||
|
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IBiomeWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IBiomeWrapper;
|
||||||
|
|
||||||
@@ -47,6 +48,7 @@ import net.minecraft.core.registries.Registries;
|
|||||||
|
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
import net.minecraft.world.level.biome.Biome;
|
import net.minecraft.world.level.biome.Biome;
|
||||||
|
|
||||||
#if MC_VER >= MC_1_18_2
|
#if MC_VER >= MC_1_18_2
|
||||||
import net.minecraft.world.level.biome.Biomes;
|
import net.minecraft.world.level.biome.Biomes;
|
||||||
#endif
|
#endif
|
||||||
@@ -56,7 +58,7 @@ import net.minecraft.world.level.biome.Biomes;
|
|||||||
public class BiomeWrapper implements IBiomeWrapper
|
public class BiomeWrapper implements IBiomeWrapper
|
||||||
{
|
{
|
||||||
// must be defined before AIR, otherwise a null pointer will be thrown
|
// must be defined before AIR, otherwise a null pointer will be thrown
|
||||||
private static final Logger LOGGER = LogManager.getLogger();
|
private static final DhLogger LOGGER = new DhLoggerBuilder().build();
|
||||||
|
|
||||||
|
|
||||||
#if MC_VER < MC_1_18_2
|
#if MC_VER < MC_1_18_2
|
||||||
@@ -102,7 +104,7 @@ public class BiomeWrapper implements IBiomeWrapper
|
|||||||
// constructors //
|
// constructors //
|
||||||
//==============//
|
//==============//
|
||||||
|
|
||||||
static public IBiomeWrapper getBiomeWrapper(#if MC_VER < MC_1_18_2 Biome #else Holder<Biome> #endif biome, ILevelWrapper levelWrapper)
|
public static BiomeWrapper getBiomeWrapper(#if MC_VER < MC_1_18_2 Biome #else Holder<Biome> #endif biome, ILevelWrapper levelWrapper)
|
||||||
{
|
{
|
||||||
if (biome == null)
|
if (biome == null)
|
||||||
{
|
{
|
||||||
@@ -110,9 +112,10 @@ public class BiomeWrapper implements IBiomeWrapper
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (WRAPPER_BY_BIOME.containsKey(biome))
|
BiomeWrapper biomeWrapper = WRAPPER_BY_BIOME.get(biome);
|
||||||
|
if (biomeWrapper != null)
|
||||||
{
|
{
|
||||||
return WRAPPER_BY_BIOME.get(biome);
|
return biomeWrapper;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -130,14 +133,6 @@ public class BiomeWrapper implements IBiomeWrapper
|
|||||||
//LOGGER.trace("Created BiomeWrapper ["+this.serialString+"] for ["+biome+"]");
|
//LOGGER.trace("Created BiomeWrapper ["+this.serialString+"] for ["+biome+"]");
|
||||||
}
|
}
|
||||||
|
|
||||||
/** should only be used to create {@link BiomeWrapper#EMPTY_WRAPPER} */
|
|
||||||
private BiomeWrapper()
|
|
||||||
{
|
|
||||||
this.biome = null;
|
|
||||||
this.serialString = EMPTY_BIOME_STRING;
|
|
||||||
this.hashCode = Objects.hash(this.serialString);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//=========//
|
//=========//
|
||||||
@@ -286,64 +281,16 @@ public class BiomeWrapper implements IBiomeWrapper
|
|||||||
BiomeWrapper foundWrapper = EMPTY_WRAPPER;
|
BiomeWrapper foundWrapper = EMPTY_WRAPPER;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// parse the resource location
|
|
||||||
int separatorIndex = resourceLocationString.indexOf(":");
|
|
||||||
if (separatorIndex == -1)
|
|
||||||
{
|
|
||||||
throw new IOException("Unable to parse resource location string: [" + resourceLocationString + "].");
|
|
||||||
}
|
|
||||||
|
|
||||||
ResourceLocation resourceLocation;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
#if MC_VER < MC_1_21_1
|
|
||||||
resourceLocation = new ResourceLocation(resourceLocationString.substring(0, separatorIndex), resourceLocationString.substring(separatorIndex + 1));
|
|
||||||
#else
|
|
||||||
resourceLocation = ResourceLocation.fromNamespaceAndPath(resourceLocationString.substring(0, separatorIndex), resourceLocationString.substring(separatorIndex + 1));
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
throw new IOException("No Resource Location found for the string: [" + resourceLocationString + "] Error: [" + e.getMessage() + "].");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Level level = (Level) levelWrapper.getWrappedMcObject();
|
Level level = (Level) levelWrapper.getWrappedMcObject();
|
||||||
net.minecraft.core.RegistryAccess registryAccess = level.registryAccess();
|
net.minecraft.core.RegistryAccess registryAccess = level.registryAccess();
|
||||||
|
|
||||||
boolean success;
|
BiomeDeserializeResult deserializeResult = deserializeBiome(resourceLocationString, registryAccess);
|
||||||
#if MC_VER == MC_1_16_5 || MC_VER == MC_1_17_1
|
|
||||||
Biome biome = registryAccess.registryOrThrow(Registry.BIOME_REGISTRY).get(resourceLocation);
|
|
||||||
success = (biome != null);
|
|
||||||
#elif MC_VER == MC_1_18_2 || MC_VER == MC_1_19_2
|
|
||||||
Biome unwrappedBiome = registryAccess.registryOrThrow(Registry.BIOME_REGISTRY).get(resourceLocation);
|
|
||||||
success = (unwrappedBiome != null);
|
|
||||||
Holder<Biome> biome = new Holder.Direct<>(unwrappedBiome);
|
|
||||||
#elif MC_VER < MC_1_21_3
|
|
||||||
Biome unwrappedBiome = registryAccess.registryOrThrow(Registries.BIOME).get(resourceLocation);
|
|
||||||
success = (unwrappedBiome != null);
|
|
||||||
Holder<Biome> biome = new Holder.Direct<>(unwrappedBiome);
|
|
||||||
#else
|
|
||||||
Holder<Biome> biome;
|
|
||||||
Optional<Holder.Reference<Biome>> optionalBiomeHolder = registryAccess.lookupOrThrow(Registries.BIOME).get(resourceLocation);
|
|
||||||
if (optionalBiomeHolder.isPresent())
|
|
||||||
{
|
|
||||||
Biome unwrappedBiome = optionalBiomeHolder.get().value();
|
|
||||||
success = (unwrappedBiome != null);
|
|
||||||
biome = new Holder.Direct<>(unwrappedBiome);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
success = false;
|
|
||||||
biome = null;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (!success)
|
if (!deserializeResult.success)
|
||||||
{
|
{
|
||||||
if (!brokenResourceLocationStrings.contains(resourceLocationString))
|
if (!brokenResourceLocationStrings.contains(resourceLocationString))
|
||||||
{
|
{
|
||||||
@@ -354,7 +301,7 @@ public class BiomeWrapper implements IBiomeWrapper
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
foundWrapper = (BiomeWrapper) getBiomeWrapper(biome, levelWrapper);
|
foundWrapper = getBiomeWrapper(deserializeResult.biome, levelWrapper);
|
||||||
return foundWrapper;
|
return foundWrapper;
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
@@ -368,4 +315,82 @@ public class BiomeWrapper implements IBiomeWrapper
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static BiomeDeserializeResult deserializeBiome(String resourceLocationString, net.minecraft.core.RegistryAccess registryAccess) throws IOException
|
||||||
|
{
|
||||||
|
// parse the resource location
|
||||||
|
int separatorIndex = resourceLocationString.indexOf(":");
|
||||||
|
if (separatorIndex == -1)
|
||||||
|
{
|
||||||
|
throw new IOException("Unable to parse resource location string: [" + resourceLocationString + "].");
|
||||||
|
}
|
||||||
|
|
||||||
|
ResourceLocation resourceLocation;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
#if MC_VER < MC_1_21_1
|
||||||
|
resourceLocation = new ResourceLocation(resourceLocationString.substring(0, separatorIndex), resourceLocationString.substring(separatorIndex + 1));
|
||||||
|
#else
|
||||||
|
resourceLocation = ResourceLocation.fromNamespaceAndPath(resourceLocationString.substring(0, separatorIndex), resourceLocationString.substring(separatorIndex + 1));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
throw new IOException("No Resource Location found for the string: [" + resourceLocationString + "] Error: [" + e.getMessage() + "].");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
boolean success;
|
||||||
|
#if MC_VER == MC_1_16_5 || MC_VER == MC_1_17_1
|
||||||
|
Biome biome = registryAccess.registryOrThrow(Registry.BIOME_REGISTRY).get(resourceLocation);
|
||||||
|
success = (biome != null);
|
||||||
|
#elif MC_VER == MC_1_18_2 || MC_VER == MC_1_19_2
|
||||||
|
Biome unwrappedBiome = registryAccess.registryOrThrow(Registry.BIOME_REGISTRY).get(resourceLocation);
|
||||||
|
success = (unwrappedBiome != null);
|
||||||
|
Holder<Biome> biome = new Holder.Direct<>(unwrappedBiome);
|
||||||
|
#elif MC_VER < MC_1_21_3
|
||||||
|
Biome unwrappedBiome = registryAccess.registryOrThrow(Registries.BIOME).get(resourceLocation);
|
||||||
|
success = (unwrappedBiome != null);
|
||||||
|
Holder<Biome> biome = new Holder.Direct<>(unwrappedBiome);
|
||||||
|
#else
|
||||||
|
Holder<Biome> biome;
|
||||||
|
Optional<Holder.Reference<Biome>> optionalBiomeHolder = registryAccess.lookupOrThrow(Registries.BIOME).get(resourceLocation);
|
||||||
|
if (optionalBiomeHolder.isPresent())
|
||||||
|
{
|
||||||
|
Biome unwrappedBiome = optionalBiomeHolder.get().value();
|
||||||
|
success = (unwrappedBiome != null);
|
||||||
|
biome = new Holder.Direct<>(unwrappedBiome);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
success = false;
|
||||||
|
biome = null;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return new BiomeDeserializeResult(success, biome);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//================//
|
||||||
|
// helper classes //
|
||||||
|
//================//
|
||||||
|
|
||||||
|
public static class BiomeDeserializeResult
|
||||||
|
{
|
||||||
|
public final boolean success;
|
||||||
|
|
||||||
|
#if MC_VER < MC_1_18_2
|
||||||
|
public final Biome biome;
|
||||||
|
#else
|
||||||
|
public final Holder<Biome> biome;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
public BiomeDeserializeResult(boolean success, #if MC_VER < MC_1_18_2 Biome #else Holder<Biome> #endif biome)
|
||||||
|
{
|
||||||
|
this.success = success;
|
||||||
|
this.biome = biome;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+80
-31
@@ -35,7 +35,7 @@ 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 org.apache.logging.log4j.Logger;
|
import com.seibel.distanthorizons.core.logging.DhLogger;
|
||||||
|
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@@ -72,7 +72,7 @@ public class BlockStateWrapper implements IBlockStateWrapper
|
|||||||
|
|
||||||
|
|
||||||
// must be defined before AIR, otherwise a null pointer will be thrown
|
// must be defined before AIR, otherwise a null pointer will be thrown
|
||||||
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
|
private static final DhLogger LOGGER = new DhLoggerBuilder().build();
|
||||||
|
|
||||||
public static final ConcurrentHashMap<BlockState, BlockStateWrapper> WRAPPER_BY_BLOCK_STATE = new ConcurrentHashMap<>();
|
public static final ConcurrentHashMap<BlockState, BlockStateWrapper> WRAPPER_BY_BLOCK_STATE = new ConcurrentHashMap<>();
|
||||||
public static final ConcurrentHashMap<String, BlockStateWrapper> WRAPPER_BY_RESOURCE_LOCATION = new ConcurrentHashMap<>();
|
public static final ConcurrentHashMap<String, BlockStateWrapper> WRAPPER_BY_RESOURCE_LOCATION = new ConcurrentHashMap<>();
|
||||||
@@ -81,6 +81,7 @@ public class BlockStateWrapper implements IBlockStateWrapper
|
|||||||
public static final BlockStateWrapper AIR = new BlockStateWrapper(null, null);
|
public static final BlockStateWrapper AIR = new BlockStateWrapper(null, null);
|
||||||
|
|
||||||
public static final String DIRT_RESOURCE_LOCATION_STRING = "minecraft:dirt";
|
public static final String DIRT_RESOURCE_LOCATION_STRING = "minecraft:dirt";
|
||||||
|
public static final String WATER_RESOURCE_LOCATION_STRING = "minecraft:water";
|
||||||
|
|
||||||
public static HashSet<IBlockStateWrapper> rendererIgnoredBlocks = null;
|
public static HashSet<IBlockStateWrapper> rendererIgnoredBlocks = null;
|
||||||
public static HashSet<IBlockStateWrapper> rendererIgnoredCaveBlocks = null;
|
public static HashSet<IBlockStateWrapper> rendererIgnoredCaveBlocks = null;
|
||||||
@@ -97,16 +98,14 @@ public class BlockStateWrapper implements IBlockStateWrapper
|
|||||||
/** technically final, but since it requires a method call to generate it can't be marked as such */
|
/** technically final, but since it requires a method call to generate it can't be marked as such */
|
||||||
private String serialString;
|
private String serialString;
|
||||||
private final int hashCode;
|
private final int hashCode;
|
||||||
/**
|
/** Should be between {@link LodUtil#BLOCK_FULLY_OPAQUE} and {@link LodUtil#BLOCK_FULLY_OPAQUE} */
|
||||||
* Cached opacity value, -1 if not populated. <br>
|
private final int opacity;
|
||||||
* Should be between {@link LodUtil#BLOCK_FULLY_OPAQUE} and {@link LodUtil#BLOCK_FULLY_OPAQUE}
|
|
||||||
*/
|
|
||||||
private int opacity = -1;
|
|
||||||
/** used by the Iris shader mod to determine how each LOD should be rendered */
|
/** used by the Iris shader mod to determine how each LOD should be rendered */
|
||||||
private byte blockMaterialId = 0;
|
private byte blockMaterialId = 0;
|
||||||
|
|
||||||
private final boolean isBeaconBlock;
|
private final boolean isBeaconBlock;
|
||||||
private final boolean isBeaconBaseBlock;
|
private final boolean isBeaconBaseBlock;
|
||||||
|
private final boolean allowsBeaconBeamPassage;
|
||||||
/** null if this block can't tint beacons */
|
/** null if this block can't tint beacons */
|
||||||
private final Color beaconTintColor;
|
private final Color beaconTintColor;
|
||||||
private final Color mapColor;
|
private final Color mapColor;
|
||||||
@@ -163,9 +162,12 @@ public class BlockStateWrapper implements IBlockStateWrapper
|
|||||||
this.serialString = this.serialize(levelWrapper);
|
this.serialString = this.serialize(levelWrapper);
|
||||||
this.hashCode = Objects.hash(this.serialString);
|
this.hashCode = Objects.hash(this.serialString);
|
||||||
this.blockMaterialId = this.calculateEDhApiBlockMaterialId().index;
|
this.blockMaterialId = this.calculateEDhApiBlockMaterialId().index;
|
||||||
|
this.opacity = this.calculateOpacity();
|
||||||
|
|
||||||
|
String lowercaseSerial = this.serialString.toLowerCase();
|
||||||
|
|
||||||
|
|
||||||
// beacon blocks
|
// beacon blocks
|
||||||
String lowercaseSerial = this.serialString.toLowerCase();
|
|
||||||
boolean isBeaconBaseBlock = false;
|
boolean isBeaconBaseBlock = false;
|
||||||
for (int i = 0; i < LodUtil.BEACON_BASE_BLOCK_NAME_LIST.size(); i++)
|
for (int i = 0; i < LodUtil.BEACON_BASE_BLOCK_NAME_LIST.size(); i++)
|
||||||
{
|
{
|
||||||
@@ -201,6 +203,39 @@ public class BlockStateWrapper implements IBlockStateWrapper
|
|||||||
this.beaconTintColor = beaconTintColor;
|
this.beaconTintColor = beaconTintColor;
|
||||||
|
|
||||||
|
|
||||||
|
// allow/deny beacon beam passage
|
||||||
|
boolean allowsBeaconBeamPassage;
|
||||||
|
if (this.blockState != null)
|
||||||
|
{
|
||||||
|
// get block properties (defaults to the values used by air)
|
||||||
|
boolean canOcclude = this.getCanOcclude();
|
||||||
|
boolean propagatesSkyLightDown = this.getPropagatesSkyLightDown();
|
||||||
|
|
||||||
|
if (lowercaseSerial.contains("minecraft:bedrock"))
|
||||||
|
{
|
||||||
|
// bedrock is a special case fully opaque block that does allow beacons through
|
||||||
|
allowsBeaconBeamPassage = true;
|
||||||
|
}
|
||||||
|
else if (propagatesSkyLightDown || !canOcclude)
|
||||||
|
{
|
||||||
|
// stairs, cake, fences, etc.
|
||||||
|
allowsBeaconBeamPassage = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// non-opaque blocks (glass, mob spawners, etc.)
|
||||||
|
// all allow beacons through
|
||||||
|
allowsBeaconBeamPassage = (this.opacity != LodUtil.BLOCK_FULLY_OPAQUE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// air allows beacons through
|
||||||
|
allowsBeaconBeamPassage = true;
|
||||||
|
}
|
||||||
|
this.allowsBeaconBeamPassage = allowsBeaconBeamPassage;
|
||||||
|
|
||||||
|
|
||||||
int mcColor = 0;
|
int mcColor = 0;
|
||||||
if (this.blockState != null)
|
if (this.blockState != null)
|
||||||
{
|
{
|
||||||
@@ -344,28 +379,12 @@ public class BlockStateWrapper implements IBlockStateWrapper
|
|||||||
//=================//
|
//=================//
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getOpacity()
|
public int getOpacity() { return this.opacity; }
|
||||||
|
private int calculateOpacity()
|
||||||
{
|
{
|
||||||
// use the cached opacity value if possible
|
// get block properties (defaults to the values used by air)
|
||||||
if (this.opacity != -1)
|
boolean canOcclude = this.getCanOcclude();
|
||||||
{
|
boolean propagatesSkyLightDown = this.getPropagatesSkyLightDown();
|
||||||
return this.opacity;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// get block properties (default to the values used by air)
|
|
||||||
boolean canOcclude = false;
|
|
||||||
boolean propagatesSkyLightDown = true;
|
|
||||||
if (this.blockState != null)
|
|
||||||
{
|
|
||||||
canOcclude = this.blockState.canOcclude();
|
|
||||||
|
|
||||||
#if MC_VER < MC_1_21_3
|
|
||||||
propagatesSkyLightDown = this.blockState.propagatesSkylightDown(EmptyBlockGetter.INSTANCE, BlockPos.ZERO);
|
|
||||||
#else
|
|
||||||
propagatesSkyLightDown = this.blockState.propagatesSkylightDown();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -398,9 +417,37 @@ public class BlockStateWrapper implements IBlockStateWrapper
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
this.opacity = opacity;
|
return opacity;
|
||||||
return this.opacity;
|
|
||||||
}
|
}
|
||||||
|
private boolean getCanOcclude()
|
||||||
|
{
|
||||||
|
// defaults to the value used by air
|
||||||
|
boolean canOcclude = false;
|
||||||
|
if (this.blockState != null)
|
||||||
|
{
|
||||||
|
canOcclude = this.blockState.canOcclude();
|
||||||
|
}
|
||||||
|
|
||||||
|
return canOcclude;
|
||||||
|
}
|
||||||
|
private boolean getPropagatesSkyLightDown()
|
||||||
|
{
|
||||||
|
// defaults to the value used by air
|
||||||
|
boolean propagatesSkyLightDown = true;
|
||||||
|
if (this.blockState != null)
|
||||||
|
{
|
||||||
|
#if MC_VER < MC_1_21_3
|
||||||
|
propagatesSkyLightDown = this.blockState.propagatesSkylightDown(EmptyBlockGetter.INSTANCE, BlockPos.ZERO);
|
||||||
|
#else
|
||||||
|
propagatesSkyLightDown = this.blockState.propagatesSkylightDown();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
return propagatesSkyLightDown;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getLightEmission() { return (this.blockState != null) ? this.blockState.getLightEmission() : 0; }
|
public int getLightEmission() { return (this.blockState != null) ? this.blockState.getLightEmission() : 0; }
|
||||||
@@ -473,6 +520,8 @@ public class BlockStateWrapper implements IBlockStateWrapper
|
|||||||
public boolean isBeaconBaseBlock() { return this.isBeaconBaseBlock; }
|
public boolean isBeaconBaseBlock() { return this.isBeaconBaseBlock; }
|
||||||
@Override
|
@Override
|
||||||
public boolean isBeaconTintBlock() { return this.beaconTintColor != null; }
|
public boolean isBeaconTintBlock() { return this.beaconTintColor != null; }
|
||||||
|
@Override
|
||||||
|
public boolean allowsBeaconBeamPassage() { return this.allowsBeaconBeamPassage; }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Color getMapColor() { return this.mapColor; }
|
public Color getMapColor() { return this.mapColor; }
|
||||||
|
|||||||
+135
-49
@@ -20,15 +20,16 @@
|
|||||||
package com.seibel.distanthorizons.common.wrappers.block;
|
package com.seibel.distanthorizons.common.wrappers.block;
|
||||||
|
|
||||||
import com.seibel.distanthorizons.common.wrappers.McObjectConverter;
|
import com.seibel.distanthorizons.common.wrappers.McObjectConverter;
|
||||||
|
import com.seibel.distanthorizons.core.dataObjects.fullData.sources.FullDataSourceV2;
|
||||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||||
import com.seibel.distanthorizons.core.pos.blockPos.DhBlockPos;
|
import com.seibel.distanthorizons.core.pos.blockPos.DhBlockPos;
|
||||||
|
import com.seibel.distanthorizons.core.pos.blockPos.DhBlockPosMutable;
|
||||||
import com.seibel.distanthorizons.core.util.ColorUtil;
|
import com.seibel.distanthorizons.core.util.ColorUtil;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
|
||||||
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.Direction;
|
import net.minecraft.core.Direction;
|
||||||
import net.minecraft.world.level.LevelReader;
|
|
||||||
import net.minecraft.world.level.block.Block;
|
import net.minecraft.world.level.block.Block;
|
||||||
import net.minecraft.world.level.block.FlowerBlock;
|
import net.minecraft.world.level.block.FlowerBlock;
|
||||||
import net.minecraft.world.level.block.LeavesBlock;
|
import net.minecraft.world.level.block.LeavesBlock;
|
||||||
@@ -39,12 +40,19 @@ import net.minecraft.util.RandomSource;
|
|||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
#endif
|
#endif
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
import org.apache.logging.log4j.Logger;
|
import com.seibel.distanthorizons.core.logging.DhLogger;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.locks.ReentrantLock;
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
|
|
||||||
|
#if MC_VER < MC_1_21_5
|
||||||
|
#else
|
||||||
|
import net.minecraft.client.renderer.block.model.BlockModelPart;
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This stores and calculates the colors
|
* This stores and calculates the colors
|
||||||
* the given {@link BlockState} should have based
|
* the given {@link BlockState} should have based
|
||||||
@@ -54,7 +62,7 @@ import java.util.concurrent.locks.ReentrantLock;
|
|||||||
*/
|
*/
|
||||||
public class ClientBlockStateColorCache
|
public class ClientBlockStateColorCache
|
||||||
{
|
{
|
||||||
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
|
private static final DhLogger LOGGER = new DhLoggerBuilder().build();
|
||||||
|
|
||||||
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<>();
|
||||||
@@ -84,13 +92,12 @@ public class ClientBlockStateColorCache
|
|||||||
private static final RandomSource RANDOM = RandomSource.create();
|
private static final RandomSource RANDOM = RandomSource.create();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
private final IClientLevelWrapper levelWrapper;
|
private final IClientLevelWrapper clientLevelWrapper;
|
||||||
private final BlockState blockState;
|
private final BlockState blockState;
|
||||||
private final LevelReader level;
|
private final BlockStateWrapper blockStateWrapper;
|
||||||
|
|
||||||
private boolean isColorResolved = false;
|
private boolean isColorResolved = false;
|
||||||
private int baseColor = 0;
|
private int baseColor = 0;
|
||||||
private boolean needShade = true;
|
|
||||||
private boolean needPostTinting = false;
|
private boolean needPostTinting = false;
|
||||||
private int tintIndex = 0;
|
private int tintIndex = 0;
|
||||||
|
|
||||||
@@ -158,17 +165,21 @@ public class ClientBlockStateColorCache
|
|||||||
0.93011117f, 0.9386859f, 0.9473069f, 0.9559735f, 0.9646866f, 0.9734455f, 0.98225087f, 0.9911022f, 1.0f
|
0.93011117f, 0.9386859f, 0.9473069f, 0.9559735f, 0.9646866f, 0.9734455f, 0.98225087f, 0.9911022f, 1.0f
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private static final ThreadLocal<TintWithoutLevelOverrider> TintWithoutLevelOverrideGetter = ThreadLocal.withInitial(() -> new TintWithoutLevelOverrider());
|
||||||
|
private static final ThreadLocal<TintGetterOverride> TintOverrideGetter = ThreadLocal.withInitial(() -> new TintGetterOverride());
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//=============//
|
//=============//
|
||||||
// constructor //
|
// constructor //
|
||||||
//=============//
|
//=============//
|
||||||
|
|
||||||
public ClientBlockStateColorCache(BlockState blockState, IClientLevelWrapper samplingLevel)
|
public ClientBlockStateColorCache(BlockState blockState, IClientLevelWrapper clientLevelWrapper)
|
||||||
{
|
{
|
||||||
this.blockState = blockState;
|
this.blockState = blockState;
|
||||||
this.levelWrapper = samplingLevel;
|
this.blockStateWrapper = BlockStateWrapper.fromBlockState(blockState, clientLevelWrapper);
|
||||||
this.level = (LevelReader) samplingLevel.getWrappedMcObject();
|
this.clientLevelWrapper = clientLevelWrapper;
|
||||||
|
|
||||||
this.resolveColors();
|
this.resolveColors();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -196,9 +207,7 @@ public class ClientBlockStateColorCache
|
|||||||
List<BakedQuad> quads = null;
|
List<BakedQuad> quads = null;
|
||||||
for (Direction direction : COLOR_RESOLUTION_DIRECTION_ORDER)
|
for (Direction direction : COLOR_RESOLUTION_DIRECTION_ORDER)
|
||||||
{
|
{
|
||||||
quads = Minecraft.getInstance().getModelManager().getBlockModelShaper().
|
quads = this.getQuadsForDirection(direction);
|
||||||
getBlockModel(this.blockState).getQuads(this.blockState, direction, RANDOM);
|
|
||||||
|
|
||||||
if (quads != null && !quads.isEmpty()
|
if (quads != null && !quads.isEmpty()
|
||||||
&& !(
|
&& !(
|
||||||
this.blockState.getBlock() instanceof RotatedPillarBlock
|
this.blockState.getBlock() instanceof RotatedPillarBlock
|
||||||
@@ -212,40 +221,53 @@ public class ClientBlockStateColorCache
|
|||||||
|
|
||||||
if (quads == null || quads.isEmpty())
|
if (quads == null || quads.isEmpty())
|
||||||
{
|
{
|
||||||
quads = Minecraft.getInstance().getModelManager().getBlockModelShaper().
|
quads = this.getUnculledQuads();
|
||||||
getBlockModel(this.blockState).getQuads(this.blockState, null, RANDOM);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (quads != null && !quads.isEmpty())
|
if (quads != null
|
||||||
|
&& !quads.isEmpty()
|
||||||
|
&& quads.get(0) != null)
|
||||||
{
|
{
|
||||||
this.needPostTinting = quads.get(0).isTinted();
|
BakedQuad firstQuad = quads.get(0);
|
||||||
this.needShade = quads.get(0).isShade();
|
|
||||||
this.tintIndex = quads.get(0).getTintIndex();
|
this.needPostTinting = firstQuad.isTinted();
|
||||||
|
#if MC_VER <= MC_1_21_4
|
||||||
|
this.tintIndex = firstQuad.getTintIndex();
|
||||||
|
#else
|
||||||
|
this.tintIndex = firstQuad.tintIndex();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if MC_VER < MC_1_17_1
|
||||||
this.baseColor = calculateColorFromTexture(
|
this.baseColor = calculateColorFromTexture(
|
||||||
#if MC_VER < MC_1_17_1 quads.get(0).sprite,
|
firstQuad.sprite,
|
||||||
#else quads.get(0).getSprite(), #endif
|
EColorMode.getColorMode(this.blockState.getBlock()));
|
||||||
ColorMode.getColorMode(this.blockState.getBlock()));
|
#elif MC_VER < MC_1_21_5
|
||||||
|
this.baseColor = calculateColorFromTexture(
|
||||||
|
firstQuad.getSprite(),
|
||||||
|
EColorMode.getColorMode(this.blockState.getBlock()));
|
||||||
|
#else
|
||||||
|
this.baseColor = calculateColorFromTexture(
|
||||||
|
firstQuad.sprite(),
|
||||||
|
EColorMode.getColorMode(this.blockState.getBlock()));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Backup method.
|
// Backup method.
|
||||||
this.needPostTinting = false;
|
this.needPostTinting = false;
|
||||||
this.needShade = false;
|
|
||||||
this.tintIndex = 0;
|
this.tintIndex = 0;
|
||||||
this.baseColor = calculateColorFromTexture(Minecraft.getInstance().getModelManager().getBlockModelShaper().getParticleIcon(this.blockState),
|
this.baseColor = this.getParticleIconColor();
|
||||||
ColorMode.getColorMode(this.blockState.getBlock()));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Liquid Block
|
// Liquid Block
|
||||||
this.needPostTinting = true;
|
this.needPostTinting = true;
|
||||||
this.needShade = false;
|
|
||||||
this.tintIndex = 0;
|
this.tintIndex = 0;
|
||||||
this.baseColor = calculateColorFromTexture(Minecraft.getInstance().getModelManager().getBlockModelShaper().getParticleIcon(this.blockState),
|
this.baseColor = this.getParticleIconColor();
|
||||||
ColorMode.getColorMode(this.blockState.getBlock()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
this.isColorResolved = true;
|
this.isColorResolved = true;
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
@@ -253,8 +275,37 @@ public class ClientBlockStateColorCache
|
|||||||
RESOLVE_LOCK.unlock();
|
RESOLVE_LOCK.unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private List<BakedQuad> getUnculledQuads() { return this.getQuadsForDirection(null); }
|
||||||
|
@Nullable
|
||||||
|
private List<BakedQuad> getQuadsForDirection(@Nullable Direction direction)
|
||||||
|
{
|
||||||
|
List<BakedQuad> quads = null;
|
||||||
|
|
||||||
|
#if MC_VER < MC_1_21_5
|
||||||
|
quads = Minecraft.getInstance().getModelManager().getBlockModelShaper().
|
||||||
|
getBlockModel(this.blockState).getQuads(this.blockState, direction, RANDOM);
|
||||||
|
#else
|
||||||
|
List<BlockModelPart> blockModelPartList = Minecraft.getInstance().getModelManager().getBlockModelShaper().
|
||||||
|
getBlockModel(this.blockState).collectParts(RANDOM);
|
||||||
|
|
||||||
|
quads = new ArrayList<>();
|
||||||
|
if (blockModelPartList != null)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < blockModelPartList.size(); i++)
|
||||||
|
{
|
||||||
|
// if direction is null this will return the unculled quads
|
||||||
|
quads.addAll(blockModelPartList.get(i).getQuads(direction));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return quads;
|
||||||
|
}
|
||||||
|
|
||||||
//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, EColorMode colorMode)
|
||||||
{
|
{
|
||||||
int count = 0;
|
int count = 0;
|
||||||
int alpha = 0;
|
int alpha = 0;
|
||||||
@@ -264,8 +315,8 @@ public class ClientBlockStateColorCache
|
|||||||
int tempColor;
|
int tempColor;
|
||||||
|
|
||||||
// don't render Chiseled blocks.
|
// don't render Chiseled blocks.
|
||||||
// Since ColorMode is set per block, you only need to check this once.
|
// Since EColorMode is set per block, you only need to check this once.
|
||||||
if (colorMode != ColorMode.Chisel)
|
if (colorMode != EColorMode.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 < getTextureHeight(texture); v++)
|
for (int v = 0; v < getTextureHeight(texture); v++)
|
||||||
@@ -283,7 +334,7 @@ public class ClientBlockStateColorCache
|
|||||||
int b = (tempColor & 0x00FF0000) >>> 16;
|
int b = (tempColor & 0x00FF0000) >>> 16;
|
||||||
int a = (tempColor & 0xFF000000) >>> 24;
|
int a = (tempColor & 0xFF000000) >>> 24;
|
||||||
int scale = 1;
|
int scale = 1;
|
||||||
if (colorMode == ColorMode.Leaves)
|
if (colorMode == EColorMode.Leaves)
|
||||||
{
|
{
|
||||||
//switch (//FIXME add config option)
|
//switch (//FIXME add config option)
|
||||||
// case BLACK:
|
// case BLACK:
|
||||||
@@ -302,11 +353,11 @@ public class ClientBlockStateColorCache
|
|||||||
// break; //do nothing, let it count towards transparency
|
// break; //do nothing, let it count towards transparency
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (a == 0 && colorMode != ColorMode.Glass)
|
else if (a == 0 && colorMode != EColorMode.Glass)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (colorMode == ColorMode.Flower && (g + 25 < b || g + 25 < r))
|
else if (colorMode == EColorMode.Flower && (g + 25 < b || g + 25 < r))
|
||||||
{
|
{
|
||||||
scale = FLOWER_COLOR_SCALE;
|
scale = FLOWER_COLOR_SCALE;
|
||||||
}
|
}
|
||||||
@@ -364,16 +415,18 @@ public class ClientBlockStateColorCache
|
|||||||
* This method was suggested by IMS from the Iris/Sodium team.
|
* This method was suggested by IMS from the Iris/Sodium team.
|
||||||
* That's where the numbers and code are based.
|
* That's where the numbers and code are based.
|
||||||
*/
|
*/
|
||||||
private static int linearToSrgb(float c)
|
private static int linearToSrgb(float color)
|
||||||
{
|
{
|
||||||
if (!(c > MIN_SRGB_BOUND)) {
|
if (!(color > MIN_SRGB_BOUND))
|
||||||
c = MIN_SRGB_BOUND;
|
{
|
||||||
|
color = MIN_SRGB_BOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c > MAX_SRGB_BOUND) {
|
if (color > MAX_SRGB_BOUND)
|
||||||
c = MAX_SRGB_BOUND;
|
{
|
||||||
|
color = MAX_SRGB_BOUND;
|
||||||
}
|
}
|
||||||
int inputBits = Float.floatToRawIntBits(c);
|
int inputBits = Float.floatToRawIntBits(color);
|
||||||
int entry = linearToSrgbTable[((inputBits - MIN_SRGB_BITS) >> 20)];
|
int entry = linearToSrgbTable[((inputBits - MIN_SRGB_BITS) >> 20)];
|
||||||
|
|
||||||
int bias = (entry >>> 16) << 9;
|
int bias = (entry >>> 16) << 9;
|
||||||
@@ -383,13 +436,20 @@ public class ClientBlockStateColorCache
|
|||||||
return (bias + (scale * t)) >>> 16;
|
return (bias + (scale * t)) >>> 16;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private int getParticleIconColor()
|
||||||
|
{
|
||||||
|
return calculateColorFromTexture(
|
||||||
|
Minecraft.getInstance().getModelManager().getBlockModelShaper().getParticleIcon(this.blockState),
|
||||||
|
EColorMode.getColorMode(this.blockState.getBlock()));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//===============//
|
//===============//
|
||||||
// public getter //
|
// public getter //
|
||||||
//===============//
|
//===============//
|
||||||
|
|
||||||
public int getColor(BiomeWrapper biome, DhBlockPos pos)
|
public int getColor(BiomeWrapper biomeWrapper, FullDataSourceV2 fullDataSource, DhBlockPos blockPos)
|
||||||
{
|
{
|
||||||
// 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)
|
||||||
@@ -413,13 +473,27 @@ public class ClientBlockStateColorCache
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
tintColor = Minecraft.getInstance().getBlockColors()
|
TintWithoutLevelOverrider tintOverride = TintWithoutLevelOverrideGetter.get();
|
||||||
.getColor(this.blockState, new TintWithoutLevelOverrider(biome, this.levelWrapper), McObjectConverter.Convert(pos), this.tintIndex);
|
tintOverride.update(biomeWrapper, this.blockStateWrapper, fullDataSource, this.clientLevelWrapper);
|
||||||
|
|
||||||
|
// try using DH's cached tint values first if possible
|
||||||
|
tintColor = tintOverride.tryGetBlockTint(new DhBlockPosMutable(blockPos));
|
||||||
|
if (tintColor == AbstractDhTintGetter.INVALID_COLOR)
|
||||||
|
{
|
||||||
|
// one or more tint values weren't calculated,
|
||||||
|
// we need MC's color resolver
|
||||||
|
tintColor = Minecraft.getInstance()
|
||||||
|
.getBlockColors()
|
||||||
|
.getColor(this.blockState,
|
||||||
|
tintOverride,
|
||||||
|
McObjectConverter.Convert(blockPos),
|
||||||
|
this.tintIndex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (UnsupportedOperationException e)
|
catch (UnsupportedOperationException e)
|
||||||
{
|
{
|
||||||
// this exception generally occurs if the tint requires other blocks besides itself
|
// this exception generally occurs if the tint requires other blocks besides itself
|
||||||
LOGGER.debug("Unable to use ["+TintWithoutLevelOverrider.class.getSimpleName()+"] to get the block tint for block: [" + this.blockState + "] and biome: [" + biome + "] at pos: " + pos + ". Error: [" + e.getMessage() + "]. Attempting to use backup method...", e);
|
LOGGER.debug("Unable to use ["+ TintWithoutLevelOverrider.class.getSimpleName()+"] to get the block tint for block: [" + this.blockState + "] and biome: [" + biomeWrapper + "] at pos: " + blockPos + ". Error: [" + e.getMessage() + "]. Attempting to use backup method...", e);
|
||||||
BLOCK_STATES_THAT_NEED_LEVEL.add(this.blockState);
|
BLOCK_STATES_THAT_NEED_LEVEL.add(this.blockState);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -427,10 +501,22 @@ public class ClientBlockStateColorCache
|
|||||||
// use the level logic only if requested
|
// use the level logic only if requested
|
||||||
if (BLOCK_STATES_THAT_NEED_LEVEL.contains(this.blockState))
|
if (BLOCK_STATES_THAT_NEED_LEVEL.contains(this.blockState))
|
||||||
{
|
{
|
||||||
// this logic can't be used all the time due to it breaking some blocks tinting
|
// the level shouldn't be used all the time due to it breaking some blocks tinting
|
||||||
// specifically oceans don't render correctly
|
// specifically oceans don't render correctly
|
||||||
tintColor = Minecraft.getInstance().getBlockColors()
|
|
||||||
.getColor(this.blockState, new TintGetterOverrideFast(this.level), McObjectConverter.Convert(pos), this.tintIndex);
|
TintGetterOverride tintOverride = TintOverrideGetter.get();
|
||||||
|
tintOverride.update(biomeWrapper, this.blockStateWrapper, fullDataSource, this.clientLevelWrapper);
|
||||||
|
|
||||||
|
tintColor = tintOverride.tryGetBlockTint(new DhBlockPosMutable(blockPos));
|
||||||
|
if (tintColor == AbstractDhTintGetter.INVALID_COLOR)
|
||||||
|
{
|
||||||
|
tintColor = Minecraft.getInstance()
|
||||||
|
.getBlockColors()
|
||||||
|
.getColor(this.blockState,
|
||||||
|
tintOverride,
|
||||||
|
McObjectConverter.Convert(blockPos),
|
||||||
|
this.tintIndex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
@@ -438,7 +524,7 @@ public class ClientBlockStateColorCache
|
|||||||
// only display the error once per block/biome type to reduce log spam
|
// only display the error once per block/biome type to reduce log spam
|
||||||
if (!BROKEN_BLOCK_STATES.contains(this.blockState))
|
if (!BROKEN_BLOCK_STATES.contains(this.blockState))
|
||||||
{
|
{
|
||||||
LOGGER.warn("Failed to get block color for block: [" + this.blockState + "] and biome: [" + biome + "] at pos: " + pos + ". Error: ["+e.getMessage() + "]. Note: future errors for this block/biome will be ignored.", e);
|
LOGGER.warn("Failed to get block color for block: [" + this.blockState + "] and biome: [" + biomeWrapper + "] at pos: " + blockPos + ". Error: ["+e.getMessage() + "]. Note: future errors for this block/biome will be ignored.", e);
|
||||||
BROKEN_BLOCK_STATES.add(this.blockState);
|
BROKEN_BLOCK_STATES.add(this.blockState);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -462,7 +548,7 @@ public class ClientBlockStateColorCache
|
|||||||
// helper classes //
|
// helper classes //
|
||||||
//================//
|
//================//
|
||||||
|
|
||||||
enum ColorMode
|
private enum EColorMode
|
||||||
{
|
{
|
||||||
Default,
|
Default,
|
||||||
Flower,
|
Flower,
|
||||||
@@ -470,7 +556,7 @@ public class ClientBlockStateColorCache
|
|||||||
Chisel,
|
Chisel,
|
||||||
Glass;
|
Glass;
|
||||||
|
|
||||||
static ColorMode getColorMode(Block block)
|
static EColorMode getColorMode(Block block)
|
||||||
{
|
{
|
||||||
if (block instanceof LeavesBlock) return Leaves;
|
if (block instanceof LeavesBlock) return Leaves;
|
||||||
if (block instanceof FlowerBlock) return Flower;
|
if (block instanceof FlowerBlock) return Flower;
|
||||||
|
|||||||
+24
-36
@@ -19,10 +19,11 @@
|
|||||||
|
|
||||||
package com.seibel.distanthorizons.common.wrappers.block;
|
package com.seibel.distanthorizons.common.wrappers.block;
|
||||||
|
|
||||||
|
import com.seibel.distanthorizons.core.dataObjects.fullData.sources.FullDataSourceV2;
|
||||||
|
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.core.Direction;
|
import net.minecraft.core.Direction;
|
||||||
import net.minecraft.world.level.*;
|
import net.minecraft.world.level.*;
|
||||||
import net.minecraft.world.level.biome.Biome;
|
|
||||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
@@ -38,9 +39,9 @@ import java.util.Optional;
|
|||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
public class TintGetterOverrideFast implements BlockAndTintGetter
|
public class TintGetterOverride extends AbstractDhTintGetter
|
||||||
{
|
{
|
||||||
LevelReader parent;
|
private LevelReader parent;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -48,7 +49,13 @@ public class TintGetterOverrideFast implements BlockAndTintGetter
|
|||||||
// constructor //
|
// constructor //
|
||||||
//=============//
|
//=============//
|
||||||
|
|
||||||
public TintGetterOverrideFast(LevelReader parent) { this.parent = parent; }
|
public TintGetterOverride() { }
|
||||||
|
|
||||||
|
public void update(LevelReader parent, BiomeWrapper biomeWrapper, BlockStateWrapper blockStateWrapper, FullDataSourceV2 fullDataSource, IClientLevelWrapper clientLevelWrapper)
|
||||||
|
{
|
||||||
|
super.update(biomeWrapper, blockStateWrapper, fullDataSource, clientLevelWrapper);
|
||||||
|
this.parent = parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -56,18 +63,6 @@ public class TintGetterOverrideFast implements BlockAndTintGetter
|
|||||||
// methods //
|
// methods //
|
||||||
//=========//
|
//=========//
|
||||||
|
|
||||||
private Biome _getBiome(BlockPos pos)
|
|
||||||
{
|
|
||||||
#if MC_VER >= MC_1_18_2
|
|
||||||
return this.parent.getBiome(pos).value();
|
|
||||||
#else
|
|
||||||
return parent.getBiome(pos);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getBlockTint(BlockPos blockPos, ColorResolver colorResolver) { return colorResolver.getColor(this._getBiome(blockPos), blockPos.getX(), blockPos.getZ()); }
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public float getShade(Direction direction, boolean bl) { return this.parent.getShade(direction, bl); }
|
public float getShade(Direction direction, boolean bl) { return this.parent.getShade(direction, bl); }
|
||||||
|
|
||||||
@@ -87,7 +82,6 @@ public class TintGetterOverrideFast implements BlockAndTintGetter
|
|||||||
@Nullable
|
@Nullable
|
||||||
public BlockEntity getBlockEntity(BlockPos blockPos) { return this.parent.getBlockEntity(blockPos); }
|
public BlockEntity getBlockEntity(BlockPos blockPos) { return this.parent.getBlockEntity(blockPos); }
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BlockState getBlockState(BlockPos blockPos) { return this.parent.getBlockState(blockPos); }
|
public BlockState getBlockState(BlockPos blockPos) { return this.parent.getBlockState(blockPos); }
|
||||||
|
|
||||||
@@ -99,26 +93,25 @@ public class TintGetterOverrideFast implements BlockAndTintGetter
|
|||||||
|
|
||||||
#if MC_VER < MC_1_21_3
|
#if MC_VER < MC_1_21_3
|
||||||
@Override
|
@Override
|
||||||
public int getMaxLightLevel() { return parent.getMaxLightLevel(); }
|
public int getMaxLightLevel() { return this.parent.getMaxLightLevel(); }
|
||||||
#else
|
#else
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Stream<BlockState> getBlockStates(AABB aABB)
|
public Stream<BlockState> getBlockStates(AABB aABB) { return this.parent.getBlockStates(aABB); }
|
||||||
{ return this.parent.getBlockStates(aABB); }
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BlockHitResult clip(ClipContext clipContext)
|
public BlockHitResult clip(ClipContext clipContext) { return this.parent.clip(clipContext); }
|
||||||
{ return this.parent.clip(clipContext); }
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Nullable
|
@Nullable
|
||||||
public BlockHitResult clipWithInteractionOverride(Vec3 vec3, Vec3 vec32, BlockPos blockPos, VoxelShape voxelShape, BlockState blockState)
|
public BlockHitResult clipWithInteractionOverride(Vec3 vec3, Vec3 vec32, BlockPos blockPos, VoxelShape voxelShape, BlockState blockState)
|
||||||
{ return this.parent.clipWithInteractionOverride(vec3, vec32, blockPos, voxelShape, blockState); }
|
{
|
||||||
|
return this.parent.clipWithInteractionOverride(vec3, vec32, blockPos, voxelShape, blockState);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double getBlockFloorHeight(VoxelShape voxelShape, Supplier<VoxelShape> supplier)
|
public double getBlockFloorHeight(VoxelShape voxelShape, Supplier<VoxelShape> supplier) { return this.parent.getBlockFloorHeight(voxelShape, supplier); }
|
||||||
{ return this.parent.getBlockFloorHeight(voxelShape, supplier); }
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double getBlockFloorHeight(BlockPos blockPos) { return this.parent.getBlockFloorHeight(blockPos); }
|
public double getBlockFloorHeight(BlockPos blockPos) { return this.parent.getBlockFloorHeight(blockPos); }
|
||||||
@@ -131,20 +124,12 @@ public class TintGetterOverrideFast implements BlockAndTintGetter
|
|||||||
public int getMaxY() { return this.parent.getMaxY(); }
|
public int getMaxY() { return this.parent.getMaxY(); }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//==============//
|
|
||||||
// post MC 1.17 //
|
|
||||||
//==============//
|
|
||||||
|
|
||||||
#if MC_VER >= MC_1_17_1
|
#if MC_VER >= MC_1_17_1
|
||||||
@Override
|
@Override
|
||||||
public <T extends BlockEntity> Optional<T> getBlockEntity(BlockPos blockPos, BlockEntityType<T> blockEntityType)
|
public <T extends BlockEntity> Optional<T> getBlockEntity(BlockPos blockPos, BlockEntityType<T> blockEntityType) { return this.parent.getBlockEntity(blockPos, blockEntityType); }
|
||||||
{ return this.parent.getBlockEntity(blockPos, blockEntityType); }
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BlockHitResult isBlockInLine(ClipBlockStateContext clipBlockStateContext)
|
public BlockHitResult isBlockInLine(ClipBlockStateContext clipBlockStateContext) { return this.parent.isBlockInLine(clipBlockStateContext); }
|
||||||
{ return this.parent.isBlockInLine(clipBlockStateContext); }
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getHeight() { return this.parent.getHeight(); }
|
public int getHeight() { return this.parent.getHeight(); }
|
||||||
@@ -165,7 +150,7 @@ public class TintGetterOverrideFast implements BlockAndTintGetter
|
|||||||
public int getMinSection() { return this.parent.getMinSection(); }
|
public int getMinSection() { return this.parent.getMinSection(); }
|
||||||
#else
|
#else
|
||||||
@Override
|
@Override
|
||||||
public int getMinSectionY() { return BlockAndTintGetter.super.getMinSectionY(); }
|
public int getMinSectionY() { return super.getMinSectionY(); }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if MC_VER < MC_1_21_3
|
#if MC_VER < MC_1_21_3
|
||||||
@@ -191,4 +176,7 @@ public class TintGetterOverrideFast implements BlockAndTintGetter
|
|||||||
@Override
|
@Override
|
||||||
public int getSectionYFromSectionIndex(int i) { return this.parent.getSectionYFromSectionIndex(i); }
|
public int getSectionYFromSectionIndex(int i) { return this.parent.getSectionYFromSectionIndex(i); }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
-214
@@ -1,214 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of the Distant Horizons mod
|
|
||||||
* licensed under the GNU LGPL v3 License.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2020 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;
|
|
||||||
|
|
||||||
import com.seibel.distanthorizons.core.util.LodUtil;
|
|
||||||
import net.minecraft.core.BlockPos;
|
|
||||||
import net.minecraft.core.Cursor3D;
|
|
||||||
import net.minecraft.core.Direction;
|
|
||||||
import net.minecraft.world.level.*;
|
|
||||||
import net.minecraft.world.level.biome.Biome;
|
|
||||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
|
||||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
|
||||||
import net.minecraft.world.level.lighting.LevelLightEngine;
|
|
||||||
import net.minecraft.world.level.material.FluidState;
|
|
||||||
import net.minecraft.world.phys.AABB;
|
|
||||||
import net.minecraft.world.phys.BlockHitResult;
|
|
||||||
import net.minecraft.world.phys.Vec3;
|
|
||||||
import net.minecraft.world.phys.shapes.VoxelShape;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.function.Supplier;
|
|
||||||
import java.util.stream.Stream;
|
|
||||||
|
|
||||||
public class TintGetterOverrideSmooth implements BlockAndTintGetter
|
|
||||||
{
|
|
||||||
LevelReader parent;
|
|
||||||
public int smoothingRange;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//=============//
|
|
||||||
// constructor //
|
|
||||||
//=============//
|
|
||||||
|
|
||||||
public TintGetterOverrideSmooth(LevelReader parent, int smoothingRange)
|
|
||||||
{
|
|
||||||
this.parent = parent;
|
|
||||||
this.smoothingRange = smoothingRange;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//=========//
|
|
||||||
// methods //
|
|
||||||
//=========//
|
|
||||||
|
|
||||||
private Biome _getBiome(BlockPos pos)
|
|
||||||
{
|
|
||||||
#if MC_VER >= MC_1_18_2
|
|
||||||
return this.parent.getBiome(pos).value();
|
|
||||||
#else
|
|
||||||
return parent.getBiome(pos);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
public int calculateBlockTint(BlockPos blockPos, ColorResolver colorResolver)
|
|
||||||
{
|
|
||||||
int i = smoothingRange;
|
|
||||||
if (i == 0)
|
|
||||||
return colorResolver.getColor(_getBiome(blockPos), blockPos.getX(), blockPos.getZ());
|
|
||||||
int j = (i * 2 + 1) * (i * 2 + 1);
|
|
||||||
int k = 0;
|
|
||||||
int l = 0;
|
|
||||||
int m = 0;
|
|
||||||
Cursor3D cursor3D = new Cursor3D(blockPos.getX() - i, blockPos.getY(), blockPos.getZ() - i, blockPos.getX() + i, blockPos.getY(), blockPos.getZ() + i);
|
|
||||||
BlockPos.MutableBlockPos mutableBlockPos = new BlockPos.MutableBlockPos();
|
|
||||||
while (cursor3D.advance())
|
|
||||||
{
|
|
||||||
mutableBlockPos.set(cursor3D.nextX(), cursor3D.nextY(), cursor3D.nextZ());
|
|
||||||
int n = colorResolver.getColor(this._getBiome(mutableBlockPos), mutableBlockPos.getX(), mutableBlockPos.getZ());
|
|
||||||
|
|
||||||
k += (n & 0xFF0000) >> 16;
|
|
||||||
l += (n & 0xFF00) >> 8;
|
|
||||||
m += n & 0xFF;
|
|
||||||
}
|
|
||||||
return (k / j & 0xFF) << 16 | (l / j & 0xFF) << 8 | m / j & 0xFF;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getBlockTint(BlockPos blockPos, ColorResolver colorResolver) { return this.calculateBlockTint(blockPos, colorResolver); }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public float getShade(Direction direction, boolean bl) { return this.parent.getShade(direction, bl); }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public LevelLightEngine getLightEngine() { return this.parent.getLightEngine(); }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getBrightness(LightLayer lightLayer, BlockPos blockPos) { return this.parent.getBrightness(lightLayer, blockPos); }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getRawBrightness(BlockPos blockPos, int i) { return this.parent.getRawBrightness(blockPos, i); }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean canSeeSky(BlockPos blockPos) { return this.parent.canSeeSky(blockPos); }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Nullable
|
|
||||||
public BlockEntity getBlockEntity(BlockPos blockPos) { return this.parent.getBlockEntity(blockPos); }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BlockState getBlockState(BlockPos blockPos) { return this.parent.getBlockState(blockPos); }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public FluidState getFluidState(BlockPos blockPos) { return this.parent.getFluidState(blockPos); }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getLightEmission(BlockPos blockPos) { return this.parent.getLightEmission(blockPos); }
|
|
||||||
|
|
||||||
#if MC_VER < MC_1_21_3
|
|
||||||
@Override
|
|
||||||
public int getMaxLightLevel() { return this.parent.getMaxLightLevel(); }
|
|
||||||
#else
|
|
||||||
#endif
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Stream<BlockState> getBlockStates(AABB aABB) { return this.parent.getBlockStates(aABB); }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BlockHitResult clip(ClipContext clipContext) { return this.parent.clip(clipContext); }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Nullable
|
|
||||||
public BlockHitResult clipWithInteractionOverride(Vec3 vec3, Vec3 vec32, BlockPos blockPos, VoxelShape voxelShape, BlockState blockState)
|
|
||||||
{
|
|
||||||
return this.parent.clipWithInteractionOverride(vec3, vec32, blockPos, voxelShape, blockState);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public double getBlockFloorHeight(VoxelShape voxelShape, Supplier<VoxelShape> supplier) { return this.parent.getBlockFloorHeight(voxelShape, supplier); }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public double getBlockFloorHeight(BlockPos blockPos) { return this.parent.getBlockFloorHeight(blockPos); }
|
|
||||||
|
|
||||||
#if MC_VER < MC_1_21_3
|
|
||||||
@Override
|
|
||||||
public int getMaxBuildHeight() { return this.parent.getMaxBuildHeight(); }
|
|
||||||
#else
|
|
||||||
@Override
|
|
||||||
public int getMaxY() { return this.parent.getMaxY(); }
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if MC_VER >= MC_1_17_1
|
|
||||||
@Override
|
|
||||||
public <T extends BlockEntity> Optional<T> getBlockEntity(BlockPos blockPos, BlockEntityType<T> blockEntityType) { return this.parent.getBlockEntity(blockPos, blockEntityType); }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BlockHitResult isBlockInLine(ClipBlockStateContext clipBlockStateContext) { return this.parent.isBlockInLine(clipBlockStateContext); }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getHeight() { return this.parent.getHeight(); }
|
|
||||||
|
|
||||||
#if MC_VER < MC_1_21_3
|
|
||||||
@Override
|
|
||||||
public int getMinBuildHeight() { return this.parent.getMinBuildHeight(); }
|
|
||||||
#else
|
|
||||||
@Override
|
|
||||||
public int getMinY() { return this.parent.getMinY(); }
|
|
||||||
#endif
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getSectionsCount() { return this.parent.getSectionsCount(); }
|
|
||||||
|
|
||||||
#if MC_VER < MC_1_21_3
|
|
||||||
@Override
|
|
||||||
public int getMinSection() { return this.parent.getMinSection(); }
|
|
||||||
#else
|
|
||||||
@Override
|
|
||||||
public int getMinSectionY() { return BlockAndTintGetter.super.getMinSectionY(); }
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if MC_VER < MC_1_21_3
|
|
||||||
@Override
|
|
||||||
public int getMaxSection() { return this.parent.getMaxSection(); }
|
|
||||||
#else
|
|
||||||
@Override
|
|
||||||
public int getMaxSectionY() { return this.parent.getMaxSectionY(); }
|
|
||||||
#endif
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isOutsideBuildHeight(BlockPos blockPos) { return this.parent.isOutsideBuildHeight(blockPos); }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isOutsideBuildHeight(int i) { return this.parent.isOutsideBuildHeight(i); }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getSectionIndex(int i) { return this.parent.getSectionIndex(i); }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getSectionIndexFromSectionY(int i) { return this.parent.getSectionIndexFromSectionY(i); }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getSectionYFromSectionIndex(int i) { return this.parent.getSectionYFromSectionIndex(i); }
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
+24
-92
@@ -19,118 +19,50 @@
|
|||||||
|
|
||||||
package com.seibel.distanthorizons.common.wrappers.block;
|
package com.seibel.distanthorizons.common.wrappers.block;
|
||||||
|
|
||||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
import com.seibel.distanthorizons.core.dataObjects.fullData.sources.FullDataSourceV2;
|
||||||
import com.seibel.distanthorizons.core.util.ColorUtil;
|
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.core.Direction;
|
import net.minecraft.core.Direction;
|
||||||
import net.minecraft.world.level.*;
|
import net.minecraft.world.level.LevelReader;
|
||||||
import net.minecraft.world.level.biome.Biome;
|
|
||||||
import net.minecraft.world.level.biome.Biomes;
|
|
||||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
import net.minecraft.world.level.lighting.LevelLightEngine;
|
import net.minecraft.world.level.lighting.LevelLightEngine;
|
||||||
import net.minecraft.world.level.material.FluidState;
|
import net.minecraft.world.level.material.FluidState;
|
||||||
import org.apache.logging.log4j.Logger;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
#if MC_VER >= MC_1_18_2
|
public class TintWithoutLevelOverrider extends AbstractDhTintGetter
|
||||||
import net.minecraft.core.Holder;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
public class TintWithoutLevelOverrider implements BlockAndTintGetter
|
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* This will only ever be null if there was an issue with {@link IClientLevelWrapper#getPlainsBiomeWrapper()}
|
//=============//
|
||||||
* but {@link Nullable} is there just in case.
|
// constructor //
|
||||||
*/
|
//=============//
|
||||||
@Nullable
|
|
||||||
private final Biome biome;
|
public TintWithoutLevelOverrider()
|
||||||
|
{ }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public TintWithoutLevelOverrider(BiomeWrapper biomeWrapper, IClientLevelWrapper clientLevelWrapper)
|
//=========//
|
||||||
{
|
// methods //
|
||||||
// try to get the wrapped biome
|
//=========//
|
||||||
Biome unwrappedBiome = null;
|
|
||||||
if (biomeWrapper.biome != null)
|
|
||||||
{
|
|
||||||
unwrappedBiome = unwrap(biomeWrapper.biome);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(unwrappedBiome == null)
|
|
||||||
{
|
|
||||||
// we are looking at the empty biome wrapper, try using plains as a backup
|
|
||||||
BiomeWrapper plainsBiomeWrapper = ((BiomeWrapper) clientLevelWrapper.getPlainsBiomeWrapper());
|
|
||||||
if (plainsBiomeWrapper != null)
|
|
||||||
{
|
|
||||||
unwrappedBiome = unwrap(plainsBiomeWrapper.biome);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.biome = unwrappedBiome;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getBlockTint(@NotNull BlockPos blockPos, @NotNull ColorResolver colorResolver)
|
public float getShade(Direction direction, boolean shade)
|
||||||
{
|
{ throw new UnsupportedOperationException("ERROR: getShade() called on TintWithoutLevelOverrider. Object is for tinting only."); }
|
||||||
if (this.biome != null)
|
|
||||||
{
|
|
||||||
return colorResolver.getColor(this.biome, blockPos.getX(), blockPos.getZ());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// hopefully unneeded debug color
|
|
||||||
return ColorUtil.CYAN;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Biome unwrap(#if MC_VER >= MC_1_18_2 Holder<Biome> #else Biome #endif biome)
|
|
||||||
{
|
|
||||||
#if MC_VER >= MC_1_18_2
|
|
||||||
return biome.value();
|
|
||||||
#else
|
|
||||||
return biome;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//================//
|
|
||||||
// unused methods //
|
|
||||||
//================//
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public float getShade(@NotNull Direction direction, boolean shade)
|
public LevelLightEngine getLightEngine()
|
||||||
{
|
{ throw new UnsupportedOperationException("ERROR: getLightEngine() called on TintWithoutLevelOverrider. Object is for tinting only."); }
|
||||||
throw new UnsupportedOperationException("ERROR: getShade() called on TintWithoutLevelOverrider. Object is for tinting only.");
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public @NotNull LevelLightEngine getLightEngine()
|
|
||||||
{
|
|
||||||
throw new UnsupportedOperationException("ERROR: getLightEngine() called on TintWithoutLevelOverrider. Object is for tinting only.");
|
|
||||||
}
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public BlockEntity getBlockEntity(@NotNull BlockPos pos)
|
public BlockEntity getBlockEntity(BlockPos pos)
|
||||||
{
|
{ throw new UnsupportedOperationException("ERROR: getBlockEntity() called on TintWithoutLevelOverrider. Object is for tinting only."); }
|
||||||
throw new UnsupportedOperationException("ERROR: getBlockEntity() called on TintWithoutLevelOverrider. Object is for tinting only.");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @NotNull BlockState getBlockState(@NotNull BlockPos pos)
|
public BlockState getBlockState(BlockPos pos)
|
||||||
{
|
{ throw new UnsupportedOperationException("ERROR: getBlockState() called on TintWithoutLevelOverrider. Object is for tinting only."); }
|
||||||
throw new UnsupportedOperationException("ERROR: getBlockState() called on TintWithoutLevelOverrider. Object is for tinting only.");
|
|
||||||
}
|
|
||||||
@Override
|
@Override
|
||||||
public @NotNull FluidState getFluidState(@NotNull BlockPos pos)
|
public FluidState getFluidState(BlockPos pos)
|
||||||
{
|
{ throw new UnsupportedOperationException("ERROR: getFluidState() called on TintWithoutLevelOverrider. Object is for tinting only."); }
|
||||||
throw new UnsupportedOperationException("ERROR: getFluidState() called on TintWithoutLevelOverrider. Object is for tinting only.");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//==============//
|
//==============//
|
||||||
@@ -146,7 +78,7 @@ public class TintWithoutLevelOverrider implements BlockAndTintGetter
|
|||||||
#if MC_VER < MC_1_21_3
|
#if MC_VER < MC_1_21_3
|
||||||
@Override
|
@Override
|
||||||
public int getMinBuildHeight()
|
public int getMinBuildHeight()
|
||||||
{ throw new UnsupportedOperationException("ERROR: getMinBuildHeight() called on TintWithoutLevelOverrider. Object is for tinting only."); }
|
{ throw new UnsupportedOperationException("ERROR: getMinBuildHeight() called on TintWithoutLevelSmoothOverrider. Object is for tinting only."); }
|
||||||
#else
|
#else
|
||||||
@Override
|
@Override
|
||||||
public int getMinY()
|
public int getMinY()
|
||||||
|
|||||||
-144
@@ -1,144 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of the Distant Horizons mod
|
|
||||||
* licensed under the GNU LGPL v3 License.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2020 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;
|
|
||||||
|
|
||||||
import net.minecraft.core.BlockPos;
|
|
||||||
import net.minecraft.core.Direction;
|
|
||||||
import net.minecraft.world.level.BlockAndTintGetter;
|
|
||||||
import net.minecraft.world.level.ColorResolver;
|
|
||||||
import net.minecraft.world.level.biome.Biome;
|
|
||||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
|
||||||
import net.minecraft.world.level.lighting.LevelLightEngine;
|
|
||||||
import net.minecraft.world.level.material.FluidState;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
#if MC_VER >= MC_1_18_2
|
|
||||||
import net.minecraft.core.Holder;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
public class TintWithoutLevelSmoothOverrider implements BlockAndTintGetter
|
|
||||||
{
|
|
||||||
final BiomeWrapper biome;
|
|
||||||
public int smoothingRange;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//=============//
|
|
||||||
// constructor //
|
|
||||||
//=============//
|
|
||||||
|
|
||||||
public TintWithoutLevelSmoothOverrider(BiomeWrapper biome, int smoothingRange)
|
|
||||||
{
|
|
||||||
this.biome = biome;
|
|
||||||
this.smoothingRange = smoothingRange;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//=========//
|
|
||||||
// methods //
|
|
||||||
//=========//
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getBlockTint(BlockPos blockPos, ColorResolver colorResolver)
|
|
||||||
{
|
|
||||||
return colorResolver.getColor(_unwrap(biome.biome), blockPos.getX(), blockPos.getZ());
|
|
||||||
}
|
|
||||||
private Biome _unwrap(#if MC_VER >= MC_1_18_2 Holder<Biome> #else Biome #endif biome)
|
|
||||||
{
|
|
||||||
#if MC_VER >= MC_1_18_2
|
|
||||||
return biome.value();
|
|
||||||
#else
|
|
||||||
return biome;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
// public int calculateBlockTint(BlockPos blockPos, ColorResolver colorResolver)
|
|
||||||
// {
|
|
||||||
// int i = smoothingRange;
|
|
||||||
// if (i == 0)
|
|
||||||
// return colorResolver.getColor(_getBiome(blockPos), blockPos.getX(), blockPos.getZ());
|
|
||||||
// int j = (i * 2 + 1) * (i * 2 + 1);
|
|
||||||
// int k = 0;
|
|
||||||
// int l = 0;
|
|
||||||
// int m = 0;
|
|
||||||
// Cursor3D cursor3D = new Cursor3D(blockPos.getX() - i, blockPos.getY(), blockPos.getZ() - i, blockPos.getX() + i, blockPos.getY(), blockPos.getZ() + i);
|
|
||||||
// BlockPos.MutableBlockPos mutableBlockPos = new BlockPos.MutableBlockPos();
|
|
||||||
// while (cursor3D.advance())
|
|
||||||
// {
|
|
||||||
// mutableBlockPos.set(cursor3D.nextX(), cursor3D.nextY(), cursor3D.nextZ());
|
|
||||||
// int n;
|
|
||||||
// if (LodCommonMain.forgeMethodCaller != null) {
|
|
||||||
// n = LodCommonMain.forgeMethodCaller.colorResolverGetColor(colorResolver, _getBiome(mutableBlockPos),
|
|
||||||
// mutableBlockPos.getX(), mutableBlockPos.getZ());
|
|
||||||
// } else {
|
|
||||||
// n = colorResolver.getColor(_getBiome(mutableBlockPos), mutableBlockPos.getX(), mutableBlockPos.getZ());
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// k += (n & 0xFF0000) >> 16;
|
|
||||||
// l += (n & 0xFF00) >> 8;
|
|
||||||
// m += n & 0xFF;
|
|
||||||
// }
|
|
||||||
// return (k / j & 0xFF) << 16 | (l / j & 0xFF) << 8 | m / j & 0xFF;
|
|
||||||
// }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public float getShade(Direction direction, boolean shade)
|
|
||||||
{ throw new UnsupportedOperationException("ERROR: getShade() called on TintWithoutLevelSmoothOverrider. Object is for tinting only."); }
|
|
||||||
@Override
|
|
||||||
public LevelLightEngine getLightEngine()
|
|
||||||
{ throw new UnsupportedOperationException("ERROR: getLightEngine() called on TintWithoutLevelSmoothOverrider. Object is for tinting only."); }
|
|
||||||
@Nullable
|
|
||||||
@Override
|
|
||||||
public BlockEntity getBlockEntity(BlockPos pos)
|
|
||||||
{ throw new UnsupportedOperationException("ERROR: getBlockEntity() called on TintWithoutLevelSmoothOverrider. Object is for tinting only."); }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BlockState getBlockState(BlockPos pos)
|
|
||||||
{ throw new UnsupportedOperationException("ERROR: getBlockState() called on TintWithoutLevelSmoothOverrider. Object is for tinting only."); }
|
|
||||||
@Override
|
|
||||||
public FluidState getFluidState(BlockPos pos)
|
|
||||||
{ throw new UnsupportedOperationException("ERROR: getFluidState() called on TintWithoutLevelSmoothOverrider. Object is for tinting only."); }
|
|
||||||
|
|
||||||
|
|
||||||
//==============//
|
|
||||||
// post MC 1.17 //
|
|
||||||
//==============//
|
|
||||||
|
|
||||||
#if MC_VER >= MC_1_17_1
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getHeight()
|
|
||||||
{ throw new UnsupportedOperationException("ERROR: getHeight() called on TintWithoutLevelSmoothOverrider. Object is for tinting only."); }
|
|
||||||
|
|
||||||
#if MC_VER < MC_1_21_3
|
|
||||||
@Override
|
|
||||||
public int getMinBuildHeight()
|
|
||||||
{ throw new UnsupportedOperationException("ERROR: getMinBuildHeight() called on TintWithoutLevelSmoothOverrider. Object is for tinting only."); }
|
|
||||||
#else
|
|
||||||
@Override
|
|
||||||
public int getMinY()
|
|
||||||
{ throw new UnsupportedOperationException("ERROR: getMinY() called on TintWithoutLevelSmoothOverrider. Object is for tinting only."); }
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}
|
|
||||||
+2
-2
@@ -38,7 +38,7 @@ import net.minecraft.world.level.chunk.ChunkAccess;
|
|||||||
import net.minecraft.world.level.chunk.ProtoChunk;
|
import net.minecraft.world.level.chunk.ProtoChunk;
|
||||||
import net.minecraft.world.level.levelgen.Heightmap;
|
import net.minecraft.world.level.levelgen.Heightmap;
|
||||||
|
|
||||||
import org.apache.logging.log4j.Logger;
|
import com.seibel.distanthorizons.core.logging.DhLogger;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
@@ -75,7 +75,7 @@ import net.minecraft.world.level.chunk.status.ChunkStatus;
|
|||||||
|
|
||||||
public class ChunkWrapper implements IChunkWrapper
|
public class ChunkWrapper implements IChunkWrapper
|
||||||
{
|
{
|
||||||
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
|
private static final DhLogger LOGGER = new DhLoggerBuilder().build();
|
||||||
|
|
||||||
/** 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(() -> new BlockPos.MutableBlockPos());
|
private static final ThreadLocal<BlockPos.MutableBlockPos> MUTABLE_BLOCK_POS_REF = ThreadLocal.withInitial(() -> new BlockPos.MutableBlockPos());
|
||||||
|
|||||||
+756
-418
File diff suppressed because it is too large
Load Diff
+89
@@ -0,0 +1,89 @@
|
|||||||
|
package com.seibel.distanthorizons.common.wrappers.gui;
|
||||||
|
|
||||||
|
#if MC_VER < MC_1_21_9
|
||||||
|
// not supported for older MC versions
|
||||||
|
#else
|
||||||
|
import com.seibel.distanthorizons.core.logging.f3.F3Screen;
|
||||||
|
import com.seibel.distanthorizons.coreapi.ModInfo;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import net.minecraft.client.gui.components.debug.DebugScreenDisplayer;
|
||||||
|
import net.minecraft.client.gui.components.debug.DebugScreenEntries;
|
||||||
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
import net.minecraft.world.level.Level;
|
||||||
|
import net.minecraft.world.level.chunk.LevelChunk;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if MC_VER < MC_1_21_9
|
||||||
|
// not supported for older MC versions
|
||||||
|
public class DhDebugScreenEntry
|
||||||
|
{}
|
||||||
|
#else
|
||||||
|
public class DhDebugScreenEntry implements net.minecraft.client.gui.components.debug.DebugScreenEntry
|
||||||
|
{
|
||||||
|
public static void register()
|
||||||
|
{
|
||||||
|
// This method is private, so its access will need to be widened
|
||||||
|
DebugScreenEntries.register(
|
||||||
|
// The id, this will be displayed on the options screen
|
||||||
|
ResourceLocation.fromNamespaceAndPath(ModInfo.RESOURCE_NAMESPACE, "distant_horizons"),
|
||||||
|
// The screen entry
|
||||||
|
new DhDebugScreenEntry()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void display(@NotNull DebugScreenDisplayer displayer, @Nullable Level level, @Nullable LevelChunk clientChunk, @Nullable LevelChunk serverChunk)
|
||||||
|
{
|
||||||
|
List<String> messageList = new ArrayList<>();
|
||||||
|
F3Screen.addStringToDisplay(messageList);
|
||||||
|
|
||||||
|
for (String message : messageList)
|
||||||
|
{
|
||||||
|
displayer.addLine(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
//// The following will display like so if it is the only entry on the screen:
|
||||||
|
//// First left! First Right!
|
||||||
|
////
|
||||||
|
//// Hello world! Random text!
|
||||||
|
//// Lorem ipsum.
|
||||||
|
//// I am another group!
|
||||||
|
//// I am one group This will appear after with no line breaks!
|
||||||
|
//// All in a row
|
||||||
|
//// Provided in a list.
|
||||||
|
////
|
||||||
|
//
|
||||||
|
//displayer.addLine("Hello world!");
|
||||||
|
//displayer.addLine("Lorem ipsum.");
|
||||||
|
//displayer.addLine("Random text!");
|
||||||
|
//
|
||||||
|
//// These will be displayed first
|
||||||
|
//displayer.addPriorityLine("First left!");
|
||||||
|
//displayer.addPriorityLine("First right!");
|
||||||
|
//
|
||||||
|
//// These will be grouped separately based on the key
|
||||||
|
//displayer.addToGroup(GROUP_ONE, List.of(
|
||||||
|
// "I am one group",
|
||||||
|
// "All in a row",
|
||||||
|
// "Provided in a list."
|
||||||
|
//));
|
||||||
|
//
|
||||||
|
//displayer.addToGroup(GROUP_TWO, "I am another group!");
|
||||||
|
//displayer.addToGroup(GROUP_TWO, "This will appear after with no line breaks!");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isAllowed(boolean reducedDebugInfo)
|
||||||
|
{
|
||||||
|
// Always show regardless of accessibility option
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
@@ -52,6 +52,27 @@ public class DhScreen extends Screen
|
|||||||
{
|
{
|
||||||
renderTooltip(guiStack, comp, x, y);
|
renderTooltip(guiStack, comp, x, y);
|
||||||
}
|
}
|
||||||
|
#elif MC_VER < MC_1_21_6
|
||||||
|
protected void DhDrawCenteredString(GuiGraphics guiStack, Font font, Component text, int x, int y, int color)
|
||||||
|
{
|
||||||
|
guiStack.drawCenteredString(font, text, x, y, color);
|
||||||
|
}
|
||||||
|
protected void DhDrawString(GuiGraphics guiStack, Font font, Component text, int x, int y, int color)
|
||||||
|
{
|
||||||
|
guiStack.drawString(font, text, x, y, color);
|
||||||
|
}
|
||||||
|
//protected void DhRenderTooltip(GuiGraphics guiStack, Font font, List<? extends net.minecraft.util.FormattedCharSequence> text, int x, int y)
|
||||||
|
//{
|
||||||
|
// guiStack.renderTooltip(font, text, x, y);
|
||||||
|
//}
|
||||||
|
protected void DhRenderComponentTooltip(GuiGraphics guiStack, Font font, List<Component> comp, int x, int y)
|
||||||
|
{
|
||||||
|
guiStack.renderComponentTooltip(font, comp, x, y);
|
||||||
|
}
|
||||||
|
protected void DhRenderTooltip(GuiGraphics guiStack, Font font, Component text, int x, int y)
|
||||||
|
{
|
||||||
|
guiStack.renderTooltip(font, text, x, y);
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
protected void DhDrawCenteredString(GuiGraphics guiStack, Font font, Component text, int x, int y, int color)
|
protected void DhDrawCenteredString(GuiGraphics guiStack, Font font, Component text, int x, int y, int color)
|
||||||
{
|
{
|
||||||
@@ -61,17 +82,20 @@ public class DhScreen extends Screen
|
|||||||
{
|
{
|
||||||
guiStack.drawString(font, text, x, y, color);
|
guiStack.drawString(font, text, x, y, color);
|
||||||
}
|
}
|
||||||
protected void DhRenderTooltip(GuiGraphics guiStack, Font font, List<? extends net.minecraft.util.FormattedCharSequence> text, int x, int y)
|
//protected void DhRenderTooltip(GuiGraphics guiStack, Font font, List<? extends net.minecraft.util.FormattedCharSequence> text, int x, int y)
|
||||||
{
|
//{
|
||||||
guiStack.renderTooltip(font, text, x, y);
|
// //guiStack.renderTooltip(font, text, x, y);
|
||||||
}
|
//}
|
||||||
protected void DhRenderComponentTooltip(GuiGraphics guiStack, Font font, List<Component> comp, int x, int y)
|
protected void DhRenderComponentTooltip(GuiGraphics guiStack, Font font, List<Component> comp, int x, int y)
|
||||||
{
|
{
|
||||||
guiStack.renderComponentTooltip(font, comp, x, y);
|
guiStack.setComponentTooltipForNextFrame(font, comp, x, y);
|
||||||
}
|
}
|
||||||
protected void DhRenderTooltip(GuiGraphics guiStack, Font font, Component text, int x, int y)
|
protected void DhRenderTooltip(GuiGraphics guiStack, Font font, Component text, int x, int y)
|
||||||
{
|
{
|
||||||
guiStack.renderTooltip(font, text, x, y);
|
guiStack.setTooltipForNextFrame(font, text, x, y);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+30
-18
@@ -1,40 +1,52 @@
|
|||||||
package com.seibel.distanthorizons.common.wrappers.gui;
|
package com.seibel.distanthorizons.common.wrappers.gui;
|
||||||
|
|
||||||
|
import com.seibel.distanthorizons.core.config.ConfigHandler;
|
||||||
|
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||||
import com.seibel.distanthorizons.coreapi.ModInfo;
|
import com.seibel.distanthorizons.coreapi.ModInfo;
|
||||||
import com.seibel.distanthorizons.core.config.ConfigBase;
|
|
||||||
import com.seibel.distanthorizons.core.config.gui.ConfigScreen;
|
|
||||||
import com.seibel.distanthorizons.core.config.gui.JavaScreenHandlerScreen;
|
import com.seibel.distanthorizons.core.config.gui.JavaScreenHandlerScreen;
|
||||||
import com.seibel.distanthorizons.core.config.gui.OpenGLConfigScreen;
|
|
||||||
import net.minecraft.client.gui.screens.Screen;
|
import net.minecraft.client.gui.screens.Screen;
|
||||||
|
import com.seibel.distanthorizons.core.logging.DhLogger;
|
||||||
|
|
||||||
public class GetConfigScreen
|
public class GetConfigScreen
|
||||||
{
|
{
|
||||||
public static type useScreen = type.Classic;
|
protected static final DhLogger LOGGER = new DhLoggerBuilder().build();
|
||||||
|
|
||||||
public enum type
|
public static EType useScreen = EType.Classic;
|
||||||
|
|
||||||
|
public enum EType
|
||||||
{
|
{
|
||||||
Classic,
|
Classic,
|
||||||
@Deprecated
|
JavaSwing;
|
||||||
OpenGL, // This was just an attempt, it didn't work out, and we are going to change to javafx soon (as soon as that works)
|
|
||||||
JavaFX;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Screen getScreen(Screen parent)
|
public static Screen getScreen(Screen parent)
|
||||||
{
|
{
|
||||||
// Generate the language
|
// TODO it'd be nice to have this run automatically on startup
|
||||||
// This shouldn't be here, but I need a way to test it after Minecraft inits its assets
|
// but this will only work once MC has added our lang file,
|
||||||
//System.out.println(ConfigBase.INSTANCE.generateLang(false, true));
|
// which won't be for sure added until we request a GUI
|
||||||
|
if (ModInfo.IS_DEV_BUILD)
|
||||||
|
{
|
||||||
|
String missingLangEntries = ConfigHandler.INSTANCE.generateLang(true, true);
|
||||||
|
|
||||||
|
// trim to remove any newlines/spaces
|
||||||
|
// that may be present when no lang entries need changing
|
||||||
|
// then we can check length != 0 if any items are missing and need adding
|
||||||
|
String trimmedMissingEntries = missingLangEntries.trim();
|
||||||
|
if (!trimmedMissingEntries.isEmpty())
|
||||||
|
{
|
||||||
|
LOGGER.warn("One or more language entries is missing:");
|
||||||
|
LOGGER.warn(missingLangEntries);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
switch (useScreen)
|
switch (useScreen)
|
||||||
{
|
{
|
||||||
case Classic:
|
case Classic:
|
||||||
return ClassicConfigGUI.getScreen(ConfigBase.INSTANCE, parent, "client");
|
return ClassicConfigGUI.getScreen(parent, "client");
|
||||||
case OpenGL:
|
case JavaSwing:
|
||||||
MinecraftScreen.getScreen(parent, new OpenGLConfigScreen(), ModInfo.ID + ".title");
|
//return MinecraftScreen.getScreen(parent, new JavaScreenHandlerScreen(new ConfigScreen()), ModInfo.ID + ".title");
|
||||||
return null;
|
return 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:
|
|
||||||
return MinecraftScreen.getScreen(parent, new JavaScreenHandlerScreen(new ConfigScreen()), ModInfo.ID + ".title");
|
|
||||||
default:
|
default:
|
||||||
throw new IllegalArgumentException("No config screen implementation defined for ["+useScreen+"].");
|
throw new IllegalArgumentException("No config screen implementation defined for ["+useScreen+"].");
|
||||||
}
|
}
|
||||||
|
|||||||
+40
-37
@@ -24,26 +24,26 @@ public class MinecraftScreen
|
|||||||
private static class ConfigScreenRenderer extends DhScreen
|
private static class ConfigScreenRenderer extends DhScreen
|
||||||
{
|
{
|
||||||
private final Screen parent;
|
private final Screen parent;
|
||||||
private ConfigListWidget list;
|
private ConfigListWidget configListWidget;
|
||||||
private AbstractScreen screen;
|
private AbstractScreen screen;
|
||||||
|
|
||||||
|
|
||||||
#if MC_VER < MC_1_19_2
|
#if MC_VER < MC_1_19_2
|
||||||
public static net.minecraft.network.chat.TranslatableComponent translate(String str, Object... args)
|
public static net.minecraft.network.chat.TranslatableComponent translate(String str, Object... args)
|
||||||
{
|
{ return new net.minecraft.network.chat.TranslatableComponent(str, args); }
|
||||||
return new net.minecraft.network.chat.TranslatableComponent(str, args);
|
|
||||||
}
|
|
||||||
#else
|
#else
|
||||||
public static net.minecraft.network.chat.MutableComponent translate(String str, Object... args)
|
public static net.minecraft.network.chat.MutableComponent translate(String str, Object... args)
|
||||||
{
|
{ return net.minecraft.network.chat.Component.translatable(str, args); }
|
||||||
return net.minecraft.network.chat.Component.translatable(str, args);
|
#endif
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
protected ConfigScreenRenderer(Screen parent, AbstractScreen screen, String translationName)
|
protected ConfigScreenRenderer(Screen parent, AbstractScreen screen, String translationName)
|
||||||
{
|
{
|
||||||
super(translate(translationName));
|
super(translate(translationName));
|
||||||
|
#if MC_VER < MC_1_21_9
|
||||||
screen.minecraftWindow = Minecraft.getInstance().getWindow().getWindow();
|
screen.minecraftWindow = Minecraft.getInstance().getWindow().getWindow();
|
||||||
|
#else
|
||||||
|
screen.minecraftWindow = Minecraft.getInstance().getWindow().handle();
|
||||||
|
#endif
|
||||||
this.parent = parent;
|
this.parent = parent;
|
||||||
this.screen = screen;
|
this.screen = screen;
|
||||||
}
|
}
|
||||||
@@ -53,20 +53,22 @@ public class MinecraftScreen
|
|||||||
{
|
{
|
||||||
super.init(); // Init Minecraft's screen
|
super.init(); // Init Minecraft's screen
|
||||||
Window mcWindow = this.minecraft.getWindow();
|
Window mcWindow = this.minecraft.getWindow();
|
||||||
screen.width = mcWindow.getWidth();
|
this.screen.width = mcWindow.getWidth();
|
||||||
screen.height = mcWindow.getHeight();
|
this.screen.height = mcWindow.getHeight();
|
||||||
screen.scaledWidth = this.width;
|
this.screen.scaledWidth = this.width;
|
||||||
screen.scaledHeight = this.height;
|
this.screen.scaledHeight = this.height;
|
||||||
screen.init(); // Init our own config screen
|
this.screen.init(); // Init our own config screen
|
||||||
|
|
||||||
this.list = new ConfigListWidget(this.minecraft, this.width, this.height, 0, 0, 25); // Select the area to tint
|
this.configListWidget = new ConfigListWidget(this.minecraft, this.width, this.height, 0, 0, 25); // Select the area to tint
|
||||||
|
|
||||||
#if MC_VER < MC_1_20_6 // no background is rendered in MC 1.20.6+
|
#if MC_VER < MC_1_20_6 // no background is rendered in MC 1.20.6+
|
||||||
if (this.minecraft != null && this.minecraft.level != null) // Check if in game
|
if (this.minecraft != null && this.minecraft.level != null) // Check if in game
|
||||||
this.list.setRenderBackground(false); // Disable from rendering
|
{
|
||||||
|
this.configListWidget.setRenderBackground(false); // Disable from rendering
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
this.addWidget(this.list); // Add the tint to the things to be rendered
|
this.addWidget(this.configListWidget); // Add the tint to the things to be rendered
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -78,14 +80,17 @@ public class MinecraftScreen
|
|||||||
{
|
{
|
||||||
#if MC_VER < MC_1_20_2
|
#if MC_VER < MC_1_20_2
|
||||||
this.renderBackground(matrices); // Render background
|
this.renderBackground(matrices); // Render background
|
||||||
#else
|
#elif MC_VER < MC_1_21_6
|
||||||
this.renderBackground(matrices, mouseX, mouseY, delta); // Render background
|
this.renderBackground(matrices, mouseX, mouseY, delta); // Render background
|
||||||
|
#else
|
||||||
|
// background blur is already being rendered, rendering again causes the game to crash
|
||||||
#endif
|
#endif
|
||||||
this.list.render(matrices, mouseX, mouseY, delta); // Renders the items in the render list (currently only used to tint background darker)
|
|
||||||
|
|
||||||
screen.mouseX = mouseX;
|
this.configListWidget.render(matrices, mouseX, mouseY, delta); // Renders the items in the render list (currently only used to tint background darker)
|
||||||
screen.mouseY = mouseY;
|
|
||||||
screen.render(delta); // Render everything on the main screen
|
this.screen.mouseX = mouseX;
|
||||||
|
this.screen.mouseY = mouseY;
|
||||||
|
this.screen.render(delta); // Render everything on the main screen
|
||||||
|
|
||||||
super.render(matrices, mouseX, mouseY, delta); // Render the vanilla stuff (currently only used for the background and tint)
|
super.render(matrices, mouseX, mouseY, delta); // Render the vanilla stuff (currently only used for the background and tint)
|
||||||
}
|
}
|
||||||
@@ -95,41 +100,39 @@ public class MinecraftScreen
|
|||||||
{
|
{
|
||||||
super.resize(mc, width, height); // Resize Minecraft's screen
|
super.resize(mc, width, height); // Resize Minecraft's screen
|
||||||
Window mcWindow = this.minecraft.getWindow();
|
Window mcWindow = this.minecraft.getWindow();
|
||||||
screen.width = mcWindow.getWidth();
|
this.screen.width = mcWindow.getWidth();
|
||||||
screen.height = mcWindow.getHeight();
|
this.screen.height = mcWindow.getHeight();
|
||||||
screen.scaledWidth = this.width;
|
this.screen.scaledWidth = this.width;
|
||||||
screen.scaledHeight = this.height;
|
this.screen.scaledHeight = this.height;
|
||||||
screen.onResize(); // Resize our screen
|
this.screen.onResize(); // Resize our screen
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void tick()
|
public void tick()
|
||||||
{
|
{
|
||||||
super.tick(); // Tick Minecraft's screen
|
super.tick(); // Tick Minecraft's screen
|
||||||
screen.tick(); // Tick our screen
|
this.screen.tick(); // Tick our screen
|
||||||
if (screen.close) // If we decide to close the screen, then actually close the screen
|
if (this.screen.close) // If we decide to close the screen, then actually close the screen
|
||||||
onClose();
|
{
|
||||||
|
this.onClose();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onClose()
|
public void onClose()
|
||||||
{
|
{
|
||||||
screen.onClose(); // Close our screen
|
this.screen.onClose(); // Close our screen
|
||||||
Objects.requireNonNull(minecraft).setScreen(this.parent); // Goto the parent screen
|
Objects.requireNonNull(this.minecraft).setScreen(this.parent); // Goto the parent screen
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onFilesDrop(@NotNull List<Path> files)
|
public void onFilesDrop(@NotNull List<Path> files)
|
||||||
{
|
{ this.screen.onFilesDrop(files); }
|
||||||
screen.onFilesDrop(files);
|
|
||||||
}
|
|
||||||
|
|
||||||
// For checking if it should close when you press the escape key
|
// For checking if it should close when you press the escape key
|
||||||
@Override
|
@Override
|
||||||
public boolean shouldCloseOnEsc()
|
public boolean shouldCloseOnEsc()
|
||||||
{
|
{ return this.screen.shouldCloseOnEsc; }
|
||||||
return screen.shouldCloseOnEsc;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+20
-2
@@ -39,9 +39,13 @@ import net.minecraft.client.renderer.GameRenderer;
|
|||||||
#elif MC_VER < MC_1_20_2
|
#elif MC_VER < MC_1_20_2
|
||||||
import net.minecraft.client.gui.components.ImageButton;
|
import net.minecraft.client.gui.components.ImageButton;
|
||||||
import net.minecraft.client.gui.GuiGraphics;
|
import net.minecraft.client.gui.GuiGraphics;
|
||||||
|
#elif MC_VER < MC_1_21_6
|
||||||
|
import net.minecraft.client.gui.GuiGraphics;
|
||||||
|
import net.minecraft.client.renderer.RenderType;
|
||||||
#else
|
#else
|
||||||
import net.minecraft.client.gui.GuiGraphics;
|
import net.minecraft.client.gui.GuiGraphics;
|
||||||
import net.minecraft.client.renderer.RenderType;
|
import net.minecraft.client.renderer.RenderType;
|
||||||
|
import net.minecraft.client.renderer.RenderPipelines;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -172,9 +176,15 @@ public class TexturedButtonWidget extends Button
|
|||||||
{
|
{
|
||||||
#if MC_VER < MC_1_21_3
|
#if MC_VER < MC_1_21_3
|
||||||
matrices.blitSprite(SPRITES.get(this.active, this.isHoveredOrFocused()), this.getX(), this.getY(), this.getWidth(), this.getHeight());
|
matrices.blitSprite(SPRITES.get(this.active, this.isHoveredOrFocused()), this.getX(), this.getY(), this.getWidth(), this.getHeight());
|
||||||
|
#elif MC_VER < MC_1_21_6
|
||||||
|
matrices.blitSprite(
|
||||||
|
RenderType::guiTextured,
|
||||||
|
SPRITES.get(this.active, this.isHoveredOrFocused()),
|
||||||
|
this.getX(), this.getY(),
|
||||||
|
this.getWidth(), this.getHeight());
|
||||||
#else
|
#else
|
||||||
matrices.blitSprite(
|
matrices.blitSprite(
|
||||||
RenderType::guiTextured,
|
RenderPipelines.GUI_TEXTURED,
|
||||||
SPRITES.get(this.active, this.isHoveredOrFocused()),
|
SPRITES.get(this.active, this.isHoveredOrFocused()),
|
||||||
this.getX(), this.getY(),
|
this.getX(), this.getY(),
|
||||||
this.getWidth(), this.getHeight());
|
this.getWidth(), this.getHeight());
|
||||||
@@ -196,7 +206,7 @@ public class TexturedButtonWidget extends Button
|
|||||||
|
|
||||||
#if MC_VER < MC_1_21_3
|
#if MC_VER < MC_1_21_3
|
||||||
matrices.blit(this.textureResourceLocation, this.getX(), this.getY(), this.u, this.v + (this.hoveredVOffset * i), this.width, this.height, this.textureWidth, this.textureHeight);
|
matrices.blit(this.textureResourceLocation, this.getX(), this.getY(), this.u, this.v + (this.hoveredVOffset * i), this.width, this.height, this.textureWidth, this.textureHeight);
|
||||||
#else
|
#elif MC_VER < MC_1_21_6
|
||||||
matrices.blit(
|
matrices.blit(
|
||||||
RenderType::guiTextured,
|
RenderType::guiTextured,
|
||||||
this.textureResourceLocation,
|
this.textureResourceLocation,
|
||||||
@@ -204,6 +214,14 @@ public class TexturedButtonWidget extends Button
|
|||||||
this.u, this.v + (this.hoveredVOffset * i),
|
this.u, this.v + (this.hoveredVOffset * i),
|
||||||
this.width, this.height,
|
this.width, this.height,
|
||||||
this.textureWidth, this.textureHeight);
|
this.textureWidth, this.textureHeight);
|
||||||
|
#else
|
||||||
|
matrices.blit(
|
||||||
|
RenderPipelines.GUI_TEXTURED,
|
||||||
|
this.textureResourceLocation,
|
||||||
|
this.getX(), this.getY(),
|
||||||
|
this.u, this.v + (this.hoveredVOffset * i),
|
||||||
|
this.width, this.height,
|
||||||
|
this.textureWidth, this.textureHeight);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|||||||
+33
@@ -0,0 +1,33 @@
|
|||||||
|
package com.seibel.distanthorizons.common.wrappers.gui.config;
|
||||||
|
|
||||||
|
import com.seibel.distanthorizons.core.config.gui.IConfigGuiInfo;
|
||||||
|
import com.seibel.distanthorizons.core.config.types.AbstractConfigBase;
|
||||||
|
import net.minecraft.client.gui.components.Button;
|
||||||
|
import net.minecraft.client.gui.components.EditBox;
|
||||||
|
import net.minecraft.network.chat.Component;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.AbstractMap;
|
||||||
|
import java.util.function.BiFunction;
|
||||||
|
import java.util.function.Function;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* holds information needed by the config GUI for rendering.
|
||||||
|
*
|
||||||
|
* @see AbstractConfigBase
|
||||||
|
*/
|
||||||
|
public class ConfigGuiInfo implements IConfigGuiInfo
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Used to display validation errors.
|
||||||
|
* Null if no error is present.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
public Component errorMessage;
|
||||||
|
|
||||||
|
public BiFunction<EditBox, Button, Predicate<String>> tooltipFunction;
|
||||||
|
/** determines which options the button will show */
|
||||||
|
public AbstractMap.SimpleEntry<Button.OnPress, Function<Object, Component>> buttonOptionMap;
|
||||||
|
|
||||||
|
}
|
||||||
+22
-25
@@ -14,7 +14,7 @@ import net.minecraft.client.gui.components.ContainerObjectSelectionList;
|
|||||||
import net.minecraft.client.gui.components.events.GuiEventListener;
|
import net.minecraft.client.gui.components.events.GuiEventListener;
|
||||||
import net.minecraft.client.gui.screens.Screen;
|
import net.minecraft.client.gui.screens.Screen;
|
||||||
import net.minecraft.network.chat.Component;
|
import net.minecraft.network.chat.Component;
|
||||||
import org.apache.logging.log4j.Logger;
|
import com.seibel.distanthorizons.core.logging.DhLogger;
|
||||||
|
|
||||||
#if MC_VER >= MC_1_17_1
|
#if MC_VER >= MC_1_17_1
|
||||||
import net.minecraft.client.gui.narration.NarratableEntry;
|
import net.minecraft.client.gui.narration.NarratableEntry;
|
||||||
@@ -41,7 +41,7 @@ import java.util.*;
|
|||||||
// TODO: Make this
|
// TODO: Make this
|
||||||
public class ChangelogScreen extends DhScreen
|
public class ChangelogScreen extends DhScreen
|
||||||
{
|
{
|
||||||
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
|
private static final DhLogger LOGGER = new DhLoggerBuilder().build();
|
||||||
|
|
||||||
|
|
||||||
private Screen parent;
|
private Screen parent;
|
||||||
@@ -74,6 +74,7 @@ public class ChangelogScreen extends DhScreen
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
this.setupChangelog(versionID);
|
this.setupChangelog(versionID);
|
||||||
@@ -175,9 +176,12 @@ public class ChangelogScreen extends DhScreen
|
|||||||
{
|
{
|
||||||
#if MC_VER < MC_1_20_2
|
#if MC_VER < MC_1_20_2
|
||||||
this.renderBackground(matrices); // Render background
|
this.renderBackground(matrices); // Render background
|
||||||
#else
|
#elif MC_VER < MC_1_21_6
|
||||||
this.renderBackground(matrices, mouseX, mouseY, delta); // Render background
|
this.renderBackground(matrices, mouseX, mouseY, delta); // Render background
|
||||||
|
#else
|
||||||
|
// background blur is already being rendered, rendering again causes the game to crash
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!this.usable)
|
if (!this.usable)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
@@ -249,42 +253,35 @@ public class ChangelogScreen extends DhScreen
|
|||||||
private final Component text;
|
private final Component text;
|
||||||
private final List<AbstractWidget> children = new ArrayList<>();
|
private final List<AbstractWidget> children = new ArrayList<>();
|
||||||
|
|
||||||
private ButtonEntry(Component text)
|
private ButtonEntry(Component text) { this.text = text; }
|
||||||
{
|
|
||||||
this.text = text;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ButtonEntry create(Component text)
|
public static ButtonEntry create(Component text)
|
||||||
{
|
{ return new ButtonEntry(text); }
|
||||||
return new ButtonEntry(text);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if MC_VER < MC_1_20_1
|
#if MC_VER < MC_1_20_1
|
||||||
@Override
|
@Override
|
||||||
public void render(PoseStack matrices, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean hovered, float tickDelta)
|
public void render(PoseStack matrices, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean hovered, float tickDelta)
|
||||||
{
|
{ GuiComponent.drawString(matrices, textRenderer, text, 12, y + 5, 0xFFFFFF); }
|
||||||
GuiComponent.drawString(matrices, textRenderer, text, 12, y + 5, 0xFFFFFF);
|
#elif MC_VER < MC_1_21_9
|
||||||
}
|
|
||||||
#else
|
|
||||||
@Override
|
@Override
|
||||||
public void render(GuiGraphics matrices, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean hovered, float tickDelta)
|
public void render(GuiGraphics matrices, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean hovered, float tickDelta)
|
||||||
{
|
{ matrices.drawString(textRenderer, this.text, 12, y + 5, 0xFFFFFF); }
|
||||||
matrices.drawString(textRenderer, this.text, 12, y + 5, 0xFFFFFF);
|
#else
|
||||||
}
|
@Override
|
||||||
|
public void renderContent(GuiGraphics matrices, int y, int x, boolean hovered, float tickDelta)
|
||||||
|
{ matrices.drawString(textRenderer, this.text, 12, y + 5, 0xFFFFFF); }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<? extends GuiEventListener> children()
|
public List<? extends GuiEventListener> children() { return this.children; }
|
||||||
{
|
|
||||||
return this.children;
|
|
||||||
}
|
|
||||||
#if MC_VER >= MC_1_17_1
|
#if MC_VER >= MC_1_17_1
|
||||||
@Override
|
@Override
|
||||||
public List<? extends NarratableEntry> narratables()
|
public List<? extends NarratableEntry> narratables() { return this.children; }
|
||||||
{
|
|
||||||
return this.children;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
+24
-8
@@ -16,7 +16,7 @@ import com.mojang.blaze3d.vertex.PoseStack;
|
|||||||
#endif
|
#endif
|
||||||
import net.minecraft.client.gui.screens.Screen;
|
import net.minecraft.client.gui.screens.Screen;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
import org.apache.logging.log4j.Logger;
|
import com.seibel.distanthorizons.core.logging.DhLogger;
|
||||||
|
|
||||||
import static com.seibel.distanthorizons.common.wrappers.gui.GuiHelper.*;
|
import static com.seibel.distanthorizons.common.wrappers.gui.GuiHelper.*;
|
||||||
|
|
||||||
@@ -31,7 +31,7 @@ import java.util.*;
|
|||||||
// and also maybe add this suggestion https://discord.com/channels/881614130614767666/1035863487110467625/1035949054485594192
|
// and also maybe add this suggestion https://discord.com/channels/881614130614767666/1035863487110467625/1035949054485594192
|
||||||
public class UpdateModScreen extends DhScreen
|
public class UpdateModScreen extends DhScreen
|
||||||
{
|
{
|
||||||
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
|
private static final DhLogger LOGGER = new DhLoggerBuilder().build();
|
||||||
|
|
||||||
|
|
||||||
private Screen parent;
|
private Screen parent;
|
||||||
@@ -169,8 +169,10 @@ public class UpdateModScreen extends DhScreen
|
|||||||
{
|
{
|
||||||
#if MC_VER < MC_1_20_2
|
#if MC_VER < MC_1_20_2
|
||||||
this.renderBackground(matrices); // Render background
|
this.renderBackground(matrices); // Render background
|
||||||
#else
|
#elif MC_VER < MC_1_21_6
|
||||||
this.renderBackground(matrices, mouseX, mouseY, delta); // Render background
|
this.renderBackground(matrices, mouseX, mouseY, delta); // Render background
|
||||||
|
#else
|
||||||
|
// background blur is already being rendered, rendering again causes the game to crash
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// TODO: add the tooltips for the buttons
|
// TODO: add the tooltips for the buttons
|
||||||
@@ -178,16 +180,30 @@ public class UpdateModScreen extends DhScreen
|
|||||||
// TODO: Add tooltips
|
// TODO: Add tooltips
|
||||||
|
|
||||||
// Render the text's
|
// Render the text's
|
||||||
DhDrawCenteredString(matrices, this.font, Translatable(ModInfo.ID + ".updater.text1"), this.width / 2, this.height / 2 - 35, 0xFFFFFF);
|
this.DhDrawCenteredString(matrices, this.font,
|
||||||
DhDrawCenteredString(matrices, this.font,
|
Translatable(ModInfo.ID + ".updater.text1"),
|
||||||
Translatable(ModInfo.ID + ".updater.text2", currentVer, nextVer),
|
this.width / 2, this.height / 2 - 35,
|
||||||
this.width / 2, this.height / 2 - 20, 0x52FD52);
|
#if MC_VER < MC_1_21_6
|
||||||
|
0xFFFFFF // RGB
|
||||||
|
#else
|
||||||
|
0xFFFFFFFF // ARGB
|
||||||
|
#endif
|
||||||
|
);
|
||||||
|
this.DhDrawCenteredString(matrices, this.font,
|
||||||
|
Translatable(ModInfo.ID + ".updater.text2", this.currentVer, this.nextVer),
|
||||||
|
this.width / 2, this.height / 2 - 20,
|
||||||
|
#if MC_VER < MC_1_21_6
|
||||||
|
0x52FD52 // RGB
|
||||||
|
#else
|
||||||
|
0xFF52FD52 // ARGB
|
||||||
|
#endif
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onClose()
|
public void onClose()
|
||||||
{
|
{
|
||||||
Objects.requireNonNull(minecraft).setScreen(this.parent); // Goto the parent screen
|
Objects.requireNonNull(this.minecraft).setScreen(this.parent); // Go to the parent screen
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
+2
-2
@@ -36,9 +36,9 @@ public class KeyedClientLevelManager implements IKeyedClientLevelManager
|
|||||||
public IServerKeyedClientLevel getServerKeyedLevel() { return this.serverKeyedLevel; }
|
public IServerKeyedClientLevel getServerKeyedLevel() { return this.serverKeyedLevel; }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IServerKeyedClientLevel setServerKeyedLevel(IClientLevelWrapper clientLevel, String levelKey)
|
public IServerKeyedClientLevel setServerKeyedLevel(IClientLevelWrapper clientLevel, String serverKey, String levelKey)
|
||||||
{
|
{
|
||||||
IServerKeyedClientLevel keyedLevel = new ServerKeyedClientLevel((ClientLevel) clientLevel.getWrappedMcObject(), levelKey);
|
IServerKeyedClientLevel keyedLevel = new ServerKeyedClientLevelWrapper((ClientLevel) clientLevel.getWrappedMcObject(), serverKey, levelKey);
|
||||||
this.serverKeyedLevel = keyedLevel;
|
this.serverKeyedLevel = keyedLevel;
|
||||||
this.enabled = true;
|
this.enabled = true;
|
||||||
return keyedLevel;
|
return keyedLevel;
|
||||||
|
|||||||
+18
-4
@@ -2,24 +2,36 @@ package com.seibel.distanthorizons.common.wrappers.level;
|
|||||||
|
|
||||||
import com.seibel.distanthorizons.common.wrappers.world.ClientLevelWrapper;
|
import com.seibel.distanthorizons.common.wrappers.world.ClientLevelWrapper;
|
||||||
import com.seibel.distanthorizons.core.level.IServerKeyedClientLevel;
|
import com.seibel.distanthorizons.core.level.IServerKeyedClientLevel;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper;
|
|
||||||
import com.seibel.distanthorizons.coreapi.util.StringUtil;
|
|
||||||
import net.minecraft.client.multiplayer.ClientLevel;
|
import net.minecraft.client.multiplayer.ClientLevel;
|
||||||
|
|
||||||
public class ServerKeyedClientLevel extends ClientLevelWrapper implements IServerKeyedClientLevel
|
public class ServerKeyedClientLevelWrapper extends ClientLevelWrapper implements IServerKeyedClientLevel
|
||||||
{
|
{
|
||||||
|
/** Returns the folder name the server wants the client to use. */
|
||||||
|
private final String serverKey;
|
||||||
|
|
||||||
/** A unique identifier (generally the level's name) for differentiating multiverse levels */
|
/** A unique identifier (generally the level's name) for differentiating multiverse levels */
|
||||||
private final String serverLevelKey;
|
private final String serverLevelKey;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public ServerKeyedClientLevel(ClientLevel level, String serverLevelKey)
|
//=============//
|
||||||
|
// constructor //
|
||||||
|
//=============//
|
||||||
|
|
||||||
|
public ServerKeyedClientLevelWrapper(ClientLevel level, String serverKey, String serverLevelKey)
|
||||||
{
|
{
|
||||||
super(level);
|
super(level);
|
||||||
|
this.serverKey = serverKey;
|
||||||
this.serverLevelKey = serverLevelKey;
|
this.serverLevelKey = serverLevelKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getServerKey() { return this.serverKey; }
|
||||||
|
|
||||||
|
//======================//
|
||||||
|
// level identification //
|
||||||
|
//======================//
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getServerLevelKey() { return this.serverLevelKey; }
|
public String getServerLevelKey() { return this.serverLevelKey; }
|
||||||
@@ -27,4 +39,6 @@ public class ServerKeyedClientLevel extends ClientLevelWrapper implements IServe
|
|||||||
@Override
|
@Override
|
||||||
public String getDhIdentifier() { return this.getServerLevelKey(); }
|
public String getDhIdentifier() { return this.getServerLevelKey(); }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
+26
-5
@@ -33,6 +33,7 @@ import com.seibel.distanthorizons.common.wrappers.world.ServerLevelWrapper;
|
|||||||
import com.seibel.distanthorizons.core.config.Config;
|
import com.seibel.distanthorizons.core.config.Config;
|
||||||
import com.seibel.distanthorizons.core.enums.EDhDirection;
|
import com.seibel.distanthorizons.core.enums.EDhDirection;
|
||||||
import com.seibel.distanthorizons.core.file.structure.ClientOnlySaveStructure;
|
import com.seibel.distanthorizons.core.file.structure.ClientOnlySaveStructure;
|
||||||
|
import com.seibel.distanthorizons.core.render.glObject.GLProxy;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
|
||||||
import com.seibel.distanthorizons.coreapi.ModInfo;
|
import com.seibel.distanthorizons.coreapi.ModInfo;
|
||||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||||
@@ -56,7 +57,7 @@ import net.minecraft.network.chat.TextComponent;
|
|||||||
import net.minecraft.server.level.ServerLevel;
|
import net.minecraft.server.level.ServerLevel;
|
||||||
import net.minecraft.util.profiling.ProfilerFiller;
|
import net.minecraft.util.profiling.ProfilerFiller;
|
||||||
import net.minecraft.world.level.ChunkPos;
|
import net.minecraft.world.level.ChunkPos;
|
||||||
import org.apache.logging.log4j.Logger;
|
import com.seibel.distanthorizons.core.logging.DhLogger;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
#if MC_VER < MC_1_21_3
|
#if MC_VER < MC_1_21_3
|
||||||
@@ -71,7 +72,7 @@ import net.minecraft.util.profiling.Profiler;
|
|||||||
*/
|
*/
|
||||||
public class MinecraftClientWrapper implements IMinecraftClientWrapper, IMinecraftSharedWrapper
|
public class MinecraftClientWrapper implements IMinecraftClientWrapper, IMinecraftSharedWrapper
|
||||||
{
|
{
|
||||||
private static final Logger LOGGER = DhLoggerBuilder.getLogger(MethodHandles.lookup().lookupClass().getSimpleName());
|
private static final DhLogger LOGGER = new DhLoggerBuilder().build();
|
||||||
private static final Minecraft MINECRAFT = Minecraft.getInstance();
|
private static final Minecraft MINECRAFT = Minecraft.getInstance();
|
||||||
|
|
||||||
public static final MinecraftClientWrapper INSTANCE = new MinecraftClientWrapper();
|
public static final MinecraftClientWrapper INSTANCE = new MinecraftClientWrapper();
|
||||||
@@ -157,9 +158,17 @@ public class MinecraftClientWrapper implements IMinecraftClientWrapper, IMinecra
|
|||||||
@Override
|
@Override
|
||||||
public boolean hasSinglePlayerServer() { return MINECRAFT.hasSingleplayerServer(); }
|
public boolean hasSinglePlayerServer() { return MINECRAFT.hasSingleplayerServer(); }
|
||||||
@Override
|
@Override
|
||||||
public boolean clientConnectedToDedicatedServer() { return MINECRAFT.getCurrentServer() != null && !this.hasSinglePlayerServer(); }
|
public boolean clientConnectedToDedicatedServer()
|
||||||
|
{
|
||||||
|
return MINECRAFT.getCurrentServer() != null
|
||||||
|
&& !this.hasSinglePlayerServer();
|
||||||
|
}
|
||||||
@Override
|
@Override
|
||||||
public boolean connectedToReplay() { return !MINECRAFT.hasSingleplayerServer() && MINECRAFT.getCurrentServer() == null; }
|
public boolean connectedToReplay()
|
||||||
|
{
|
||||||
|
return MINECRAFT.getCurrentServer() == null
|
||||||
|
&& !this.hasSinglePlayerServer() ;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getCurrentServerName()
|
public String getCurrentServerName()
|
||||||
@@ -306,10 +315,22 @@ public class MinecraftClientWrapper implements IMinecraftClientWrapper, IMinecra
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!GLProxy.hasInstance())
|
||||||
|
{
|
||||||
|
// rendering setup hasn't finished
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
#if MC_VER < MC_1_19_2
|
#if MC_VER < MC_1_19_2
|
||||||
player.sendMessage(new TextComponent(string), getPlayer().getUUID());
|
player.sendMessage(new TextComponent(string), getPlayer().getUUID());
|
||||||
#else
|
#elif MC_VER < MC_1_21_9
|
||||||
player.displayClientMessage(net.minecraft.network.chat.Component.translatable(string), /*isOverlay*/false);
|
player.displayClientMessage(net.minecraft.network.chat.Component.translatable(string), /*isOverlay*/false);
|
||||||
|
#else
|
||||||
|
|
||||||
|
GLProxy.getInstance().queueRunningOnRenderThread(() ->
|
||||||
|
{
|
||||||
|
player.displayClientMessage(net.minecraft.network.chat.Component.translatable(string), /*isOverlay*/false);
|
||||||
|
});
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+11
-4
@@ -19,12 +19,16 @@
|
|||||||
|
|
||||||
package com.seibel.distanthorizons.common.wrappers.minecraft;
|
package com.seibel.distanthorizons.common.wrappers.minecraft;
|
||||||
|
|
||||||
|
#if MC_VER < MC_1_21_5
|
||||||
import com.mojang.blaze3d.platform.GlStateManager;
|
import com.mojang.blaze3d.platform.GlStateManager;
|
||||||
|
#else
|
||||||
|
import com.mojang.blaze3d.opengl.GlStateManager;
|
||||||
|
#endif
|
||||||
|
|
||||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftGLWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftGLWrapper;
|
||||||
|
|
||||||
import org.apache.logging.log4j.Logger;
|
import com.seibel.distanthorizons.core.logging.DhLogger;
|
||||||
import org.lwjgl.opengl.GL32;
|
import org.lwjgl.opengl.GL32;
|
||||||
|
|
||||||
|
|
||||||
@@ -50,7 +54,7 @@ public class MinecraftGLWrapper implements IMinecraftGLWrapper
|
|||||||
{
|
{
|
||||||
public static final MinecraftGLWrapper INSTANCE = new MinecraftGLWrapper();
|
public static final MinecraftGLWrapper INSTANCE = new MinecraftGLWrapper();
|
||||||
|
|
||||||
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
|
private static final DhLogger LOGGER = new DhLoggerBuilder().build();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -148,7 +152,10 @@ public class MinecraftGLWrapper implements IMinecraftGLWrapper
|
|||||||
public void glBlendFunc(int sfactor, int dfactor)
|
public void glBlendFunc(int sfactor, int dfactor)
|
||||||
{
|
{
|
||||||
GL32.glBlendFunc(sfactor, dfactor);
|
GL32.glBlendFunc(sfactor, dfactor);
|
||||||
GlStateManager._blendFunc(sfactor, dfactor);
|
|
||||||
|
#if MC_VER < MC_1_21_5
|
||||||
|
GlStateManager._blendFunc(sfactor, dfactor);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
/** @see GL32#glBlendFuncSeparate */
|
/** @see GL32#glBlendFuncSeparate */
|
||||||
@Override
|
@Override
|
||||||
@@ -226,7 +233,7 @@ public class MinecraftGLWrapper implements IMinecraftGLWrapper
|
|||||||
GlStateManager._activeTexture(textureId);
|
GlStateManager._activeTexture(textureId);
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public int getActiveTexture() { return GL32.glGetInteger(GL32.GL_ACTIVE_TEXTURE); }
|
public int getActiveTexture() { return GL32.glGetInteger(GL32.GL_TEXTURE_BINDING_2D); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Always binds to {@link GL32#GL_TEXTURE_2D}
|
* Always binds to {@link GL32#GL_TEXTURE_2D}
|
||||||
|
|||||||
+168
-29
@@ -25,7 +25,6 @@ import java.util.concurrent.ConcurrentHashMap;
|
|||||||
|
|
||||||
import com.mojang.blaze3d.pipeline.RenderTarget;
|
import com.mojang.blaze3d.pipeline.RenderTarget;
|
||||||
import com.mojang.blaze3d.platform.NativeImage;
|
import com.mojang.blaze3d.platform.NativeImage;
|
||||||
import com.seibel.distanthorizons.common.wrappers.WrapperFactory;
|
|
||||||
import com.seibel.distanthorizons.common.wrappers.misc.LightMapWrapper;
|
import com.seibel.distanthorizons.common.wrappers.misc.LightMapWrapper;
|
||||||
import com.seibel.distanthorizons.core.dependencyInjection.ModAccessorInjector;
|
import com.seibel.distanthorizons.core.dependencyInjection.ModAccessorInjector;
|
||||||
|
|
||||||
@@ -33,9 +32,12 @@ import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
|||||||
import com.seibel.distanthorizons.core.util.ColorUtil;
|
import com.seibel.distanthorizons.core.util.ColorUtil;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.misc.ILightMapWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.misc.ILightMapWrapper;
|
||||||
|
|
||||||
#if MC_VER >= MC_1_17_1
|
#if MC_VER < MC_1_17_1
|
||||||
|
#elif MC_VER < MC_1_21_6
|
||||||
import net.minecraft.client.renderer.FogRenderer;
|
import net.minecraft.client.renderer.FogRenderer;
|
||||||
import com.mojang.blaze3d.systems.RenderSystem;
|
import com.mojang.blaze3d.systems.RenderSystem;
|
||||||
|
#else
|
||||||
|
import net.minecraft.client.renderer.fog.FogRenderer;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if MC_VER < MC_1_19_4
|
#if MC_VER < MC_1_19_4
|
||||||
@@ -43,8 +45,6 @@ import org.joml.Matrix4f;
|
|||||||
import org.joml.Vector3f;
|
import org.joml.Vector3f;
|
||||||
#else
|
#else
|
||||||
#endif
|
#endif
|
||||||
#if MC_VER >= MC_1_20_2
|
|
||||||
#endif
|
|
||||||
|
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.AbstractOptifineAccessor;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.AbstractOptifineAccessor;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
|
||||||
@@ -59,6 +59,12 @@ import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IOptifineAc
|
|||||||
import net.minecraft.client.Camera;
|
import net.minecraft.client.Camera;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.world.effect.MobEffects;
|
import net.minecraft.world.effect.MobEffects;
|
||||||
|
|
||||||
|
import net.minecraft.world.phys.Vec3;
|
||||||
|
import com.seibel.distanthorizons.core.logging.DhLogger;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.joml.Vector4f;
|
||||||
|
|
||||||
#if MC_VER < MC_1_17_1
|
#if MC_VER < MC_1_17_1
|
||||||
import net.minecraft.tags.FluidTags;
|
import net.minecraft.tags.FluidTags;
|
||||||
import net.minecraft.world.entity.Entity;
|
import net.minecraft.world.entity.Entity;
|
||||||
@@ -67,26 +73,22 @@ import org.lwjgl.opengl.GL15;
|
|||||||
#else
|
#else
|
||||||
import net.minecraft.world.level.material.FogType;
|
import net.minecraft.world.level.material.FogType;
|
||||||
#endif
|
#endif
|
||||||
import net.minecraft.world.phys.Vec3;
|
|
||||||
import org.apache.logging.log4j.Logger;
|
|
||||||
import org.joml.Vector4f;
|
|
||||||
|
|
||||||
|
#if MC_VER >= MC_1_21_5
|
||||||
|
import com.mojang.blaze3d.opengl.GlTexture;
|
||||||
|
#else
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A singleton that contains everything
|
* A singleton that contains everything
|
||||||
* related to rendering in Minecraft.
|
* related to rendering in Minecraft.
|
||||||
*
|
|
||||||
* @author James Seibel
|
|
||||||
* @version 12-12-2021
|
|
||||||
*/
|
*/
|
||||||
//@Environment(EnvType.CLIENT)
|
|
||||||
public class MinecraftRenderWrapper implements IMinecraftRenderWrapper
|
public class MinecraftRenderWrapper implements IMinecraftRenderWrapper
|
||||||
{
|
{
|
||||||
public static final MinecraftRenderWrapper INSTANCE = new MinecraftRenderWrapper();
|
public static final MinecraftRenderWrapper INSTANCE = new MinecraftRenderWrapper();
|
||||||
|
|
||||||
private static final Logger LOGGER = DhLoggerBuilder.getLogger(MethodHandles.lookup().lookupClass().getSimpleName());
|
private static final DhLogger LOGGER = new DhLoggerBuilder().build();
|
||||||
private static final Minecraft MC = Minecraft.getInstance();
|
private static final Minecraft MC = Minecraft.getInstance();
|
||||||
private static final IWrapperFactory FACTORY = WrapperFactory.INSTANCE;
|
|
||||||
|
|
||||||
private static final IOptifineAccessor OPTIFINE_ACCESSOR = ModAccessorInjector.INSTANCE.get(IOptifineAccessor.class);
|
private static final IOptifineAccessor OPTIFINE_ACCESSOR = ModAccessorInjector.INSTANCE.get(IOptifineAccessor.class);
|
||||||
|
|
||||||
@@ -102,7 +104,19 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper
|
|||||||
*/
|
*/
|
||||||
public int finalLevelFrameBufferId = -1;
|
public int finalLevelFrameBufferId = -1;
|
||||||
|
|
||||||
|
public boolean colorTextureCastFailLogged = false;
|
||||||
|
public boolean depthTextureCastFailLogged = false;
|
||||||
|
|
||||||
|
#if MC_VER < MC_1_21_6
|
||||||
|
#else
|
||||||
|
private static FogRenderer mcFogRenderer = null;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//=========//
|
||||||
|
// methods //
|
||||||
|
//=========//
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Vec3f getLookAtVector()
|
public Vec3f getLookAtVector()
|
||||||
@@ -115,11 +129,22 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper
|
|||||||
/** 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()
|
||||||
{
|
{
|
||||||
return MC.player.getActiveEffectsMap().get(MobEffects.BLINDNESS) != null
|
if (MC.player == null)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if (MC.player.getActiveEffectsMap() == null)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return MC.player.getActiveEffectsMap().get(MobEffects.BLINDNESS) != null
|
||||||
#if MC_VER >= MC_1_19_2
|
#if MC_VER >= MC_1_19_2
|
||||||
|| MC.player.getActiveEffectsMap().get(MobEffects.DARKNESS) != null // Deep dark effect
|
|| MC.player.getActiveEffectsMap().get(MobEffects.DARKNESS) != null // Deep dark effect
|
||||||
#endif
|
#endif
|
||||||
;
|
;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -152,7 +177,7 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper
|
|||||||
Math.max(0f, Math.min(colorValues[2], 1f)), // b
|
Math.max(0f, Math.min(colorValues[2], 1f)), // b
|
||||||
Math.max(0f, Math.min(colorValues[3], 1f)) // a
|
Math.max(0f, Math.min(colorValues[3], 1f)) // a
|
||||||
);
|
);
|
||||||
#else
|
#elif MC_VER < MC_1_21_6
|
||||||
Vector4f colorValues = FogRenderer.computeFogColor(MC.gameRenderer.getMainCamera(), partialTicks, MC.level, 1, MC.gameRenderer.getDarkenWorldAmount(partialTicks));
|
Vector4f colorValues = FogRenderer.computeFogColor(MC.gameRenderer.getMainCamera(), partialTicks, MC.level, 1, MC.gameRenderer.getDarkenWorldAmount(partialTicks));
|
||||||
return new Color(
|
return new Color(
|
||||||
Math.max(0f, Math.min(colorValues.x, 1f)), // r
|
Math.max(0f, Math.min(colorValues.x, 1f)), // r
|
||||||
@@ -160,6 +185,31 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper
|
|||||||
Math.max(0f, Math.min(colorValues.z, 1f)), // b
|
Math.max(0f, Math.min(colorValues.z, 1f)), // b
|
||||||
Math.max(0f, Math.min(colorValues.w, 1f)) // a
|
Math.max(0f, Math.min(colorValues.w, 1f)) // a
|
||||||
);
|
);
|
||||||
|
#else
|
||||||
|
|
||||||
|
if (mcFogRenderer == null)
|
||||||
|
{
|
||||||
|
mcFogRenderer = new FogRenderer();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (MC.level == null)
|
||||||
|
{
|
||||||
|
// shouldn't happen, but just in case
|
||||||
|
return Color.white;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean isFoggy =
|
||||||
|
MC.level.effects().isFoggyAt(
|
||||||
|
MC.gameRenderer.getMainCamera().getBlockPosition().getX(),
|
||||||
|
MC.gameRenderer.getMainCamera().getBlockPosition().getZ())
|
||||||
|
|| MC.gui.getBossOverlay().shouldCreateWorldFog();
|
||||||
|
Vector4f colorValues = mcFogRenderer.setupFog(MC.gameRenderer.getMainCamera(), MC.options.getEffectiveRenderDistance(), isFoggy, MC.deltaTracker, MC.gameRenderer.getDarkenWorldAmount(MC.deltaTracker.getGameTimeDeltaPartialTick(true)), MC.level);
|
||||||
|
return new Color(
|
||||||
|
Math.max(0f, Math.min(colorValues.x, 1f)), // r
|
||||||
|
Math.max(0f, Math.min(colorValues.y, 1f)), // g
|
||||||
|
Math.max(0f, Math.min(colorValues.z, 1f)), // b
|
||||||
|
Math.max(0f, Math.min(colorValues.w, 1f)) // a
|
||||||
|
);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
// getSpecialFogColor() is the same as getFogColor()
|
// getSpecialFogColor() is the same as getFogColor()
|
||||||
@@ -248,10 +298,30 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper
|
|||||||
return height;
|
return height;
|
||||||
}
|
}
|
||||||
|
|
||||||
private RenderTarget getRenderTarget() { return MC.getMainRenderTarget(); }
|
protected RenderTarget getRenderTarget() { return MC.getMainRenderTarget(); }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getTargetFrameBuffer()
|
public boolean mcRendersToFrameBuffer()
|
||||||
|
{
|
||||||
|
#if MC_VER < MC_1_21_5
|
||||||
|
return true;
|
||||||
|
#else
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean runningLegacyOpenGL()
|
||||||
|
{
|
||||||
|
#if MC_VER <= MC_1_16_5
|
||||||
|
return true;
|
||||||
|
#else
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getTargetFramebuffer()
|
||||||
{
|
{
|
||||||
// used so we can access the framebuffer shaders end up rendering to
|
// used so we can access the framebuffer shaders end up rendering to
|
||||||
if (AbstractOptifineAccessor.optifinePresent())
|
if (AbstractOptifineAccessor.optifinePresent())
|
||||||
@@ -259,31 +329,100 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper
|
|||||||
return this.finalLevelFrameBufferId;
|
return this.finalLevelFrameBufferId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if MC_VER < MC_1_21_5
|
||||||
return this.getRenderTarget().frameBufferId;
|
return this.getRenderTarget().frameBufferId;
|
||||||
|
#else
|
||||||
|
// MC renders to a texture and then directly to the default FBO now
|
||||||
|
// we need to draw to their texture instead of the FBO
|
||||||
|
return 0; // 0 is the ID for the default frame buffer
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void clearTargetFrameBuffer() { this.finalLevelFrameBufferId = -1; }
|
public void clearTargetFrameBuffer() { this.finalLevelFrameBufferId = -1; }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getDepthTextureId() { return this.getRenderTarget().getDepthTextureId(); }
|
public int getDepthTextureId()
|
||||||
@Override
|
|
||||||
public int getColorTextureId() { return this.getRenderTarget().getColorTextureId(); }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getTargetFrameBufferViewportWidth()
|
|
||||||
{
|
{
|
||||||
return getRenderTarget().viewWidth;
|
#if MC_VER < MC_1_21_5
|
||||||
|
return this.getRenderTarget().getDepthTextureId();
|
||||||
|
#else
|
||||||
|
try
|
||||||
|
{
|
||||||
|
GlTexture glTexture = (GlTexture) this.getRenderTarget().getDepthTexture();
|
||||||
|
if (glTexture == null)
|
||||||
|
{
|
||||||
|
// shouldn't happen, but just in case
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return glTexture.glId();
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
// only log this error once per session
|
||||||
|
if (!this.depthTextureCastFailLogged)
|
||||||
|
{
|
||||||
|
this.depthTextureCastFailLogged = true;
|
||||||
|
LOGGER.error("Unable to cast render Target depth texture to GlTexture. MC or a rendering mod may have changed the object type.", e);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public int getColorTextureId()
|
||||||
|
{
|
||||||
|
#if MC_VER < MC_1_21_5
|
||||||
|
return this.getRenderTarget().getColorTextureId();
|
||||||
|
#else
|
||||||
|
try
|
||||||
|
{
|
||||||
|
GlTexture glTexture = (GlTexture) this.getRenderTarget().getColorTexture();
|
||||||
|
if (glTexture == null)
|
||||||
|
{
|
||||||
|
// shouldn't happen, but just in case
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return glTexture.glId();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
// only log this error once per session
|
||||||
|
if (!this.colorTextureCastFailLogged)
|
||||||
|
{
|
||||||
|
this.colorTextureCastFailLogged = true;
|
||||||
|
LOGGER.error("Unable to cast render Target color texture to GlTexture. MC or a rendering mod may have changed the object type.", e);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getTargetFrameBufferViewportHeight()
|
public int getTargetFramebufferViewportWidth()
|
||||||
{
|
{
|
||||||
return getRenderTarget().viewHeight;
|
#if MC_VER < MC_1_21_9
|
||||||
|
return this.getRenderTarget().viewWidth;
|
||||||
|
#else
|
||||||
|
return this.getRenderTarget().width;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ILightMapWrapper getLightmapWrapper(ILevelWrapper level) { return this.lightmapByDimensionType.get(level.getDimensionType()); }
|
public int getTargetFramebufferViewportHeight()
|
||||||
|
{
|
||||||
|
#if MC_VER < MC_1_21_9
|
||||||
|
return this.getRenderTarget().viewHeight;
|
||||||
|
#else
|
||||||
|
return this.getRenderTarget().height;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ILightMapWrapper getLightmapWrapper(@NotNull ILevelWrapper level) { return this.lightmapByDimensionType.get(level.getDimensionType()); }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isFogStateSpecial()
|
public boolean isFogStateSpecial()
|
||||||
|
|||||||
+10
-2
@@ -24,7 +24,7 @@ import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
|||||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftGLWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftGLWrapper;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.misc.ILightMapWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.misc.ILightMapWrapper;
|
||||||
import org.apache.logging.log4j.Logger;
|
import com.seibel.distanthorizons.core.logging.DhLogger;
|
||||||
import org.lwjgl.opengl.GL32;
|
import org.lwjgl.opengl.GL32;
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
@@ -32,7 +32,7 @@ import java.nio.ByteBuffer;
|
|||||||
public class LightMapWrapper implements ILightMapWrapper
|
public class LightMapWrapper implements ILightMapWrapper
|
||||||
{
|
{
|
||||||
private static final IMinecraftGLWrapper GLMC = SingletonInjector.INSTANCE.get(IMinecraftGLWrapper.class);
|
private static final IMinecraftGLWrapper GLMC = SingletonInjector.INSTANCE.get(IMinecraftGLWrapper.class);
|
||||||
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
|
private static final DhLogger LOGGER = new DhLoggerBuilder().build();
|
||||||
|
|
||||||
private int textureId = 0;
|
private int textureId = 0;
|
||||||
|
|
||||||
@@ -52,6 +52,7 @@ public class LightMapWrapper implements ILightMapWrapper
|
|||||||
|
|
||||||
public void uploadLightmap(NativeImage image)
|
public void uploadLightmap(NativeImage image)
|
||||||
{
|
{
|
||||||
|
#if MC_VER < MC_1_21_5
|
||||||
int currentTexture = GLMC.getActiveTexture();
|
int currentTexture = GLMC.getActiveTexture();
|
||||||
if (this.textureId == 0)
|
if (this.textureId == 0)
|
||||||
{
|
{
|
||||||
@@ -69,13 +70,20 @@ public class LightMapWrapper implements ILightMapWrapper
|
|||||||
{
|
{
|
||||||
GLMC.glBindTexture(currentTexture);
|
GLMC.glBindTexture(currentTexture);
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
throw new UnsupportedOperationException("setLightmapId should be used for MC versions after 1.21.5"); // TODO that MC version number is wrong, when did we actually start using setLightmapId()?
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
private void createLightmap(NativeImage image)
|
private void createLightmap(NativeImage image)
|
||||||
{
|
{
|
||||||
|
#if MC_VER < MC_1_21_5
|
||||||
this.textureId = GLMC.glGenTextures();
|
this.textureId = GLMC.glGenTextures();
|
||||||
GLMC.glBindTexture(this.textureId);
|
GLMC.glBindTexture(this.textureId);
|
||||||
GL32.glTexImage2D(GL32.GL_TEXTURE_2D, 0, image.format().glFormat(), image.getWidth(), image.getHeight(),
|
GL32.glTexImage2D(GL32.GL_TEXTURE_2D, 0, image.format().glFormat(), image.getWidth(), image.getHeight(),
|
||||||
0, image.format().glFormat(), GL32.GL_UNSIGNED_BYTE, (ByteBuffer) null);
|
0, image.format().glFormat(), GL32.GL_UNSIGNED_BYTE, (ByteBuffer) null);
|
||||||
|
#else
|
||||||
|
throw new UnsupportedOperationException("setLightmapId should be used for MC versions after 1.21.5"); // TODO that MC version number is wrong, when did we actually start using setLightmapId()?
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setLightmapId(int minecraftLightmapTetxureId)
|
public void setLightmapId(int minecraftLightmapTetxureId)
|
||||||
|
|||||||
+3
-14
@@ -54,8 +54,10 @@ public class ServerPlayerWrapper implements IServerPlayerWrapper
|
|||||||
{
|
{
|
||||||
#if MC_VER < MC_1_20_1
|
#if MC_VER < MC_1_20_1
|
||||||
level = this.getServerPlayer().getLevel();
|
level = this.getServerPlayer().getLevel();
|
||||||
#else
|
#elif MC_VER < MC_1_21_6
|
||||||
level = this.getServerPlayer().serverLevel();
|
level = this.getServerPlayer().serverLevel();
|
||||||
|
#else
|
||||||
|
level = this.getServerPlayer().level();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -69,19 +71,6 @@ public class ServerPlayerWrapper implements IServerPlayerWrapper
|
|||||||
return new Vec3d(position.x, position.y, position.z);
|
return new Vec3d(position.x, position.y, position.z);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getViewDistance() { return this.getServerPlayer().server.getPlayerList().getViewDistance(); }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public SocketAddress getRemoteAddress()
|
|
||||||
{
|
|
||||||
#if MC_VER >= MC_1_19_4
|
|
||||||
return this.getServerPlayer().connection.getRemoteAddress();
|
|
||||||
#else // < 1.19.4
|
|
||||||
return this.getServerPlayer().connection.connection.getRemoteAddress();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//================//
|
//================//
|
||||||
|
|||||||
+100
-65
@@ -2,11 +2,11 @@ package com.seibel.distanthorizons.common.wrappers.world;
|
|||||||
|
|
||||||
import com.seibel.distanthorizons.api.enums.worldGeneration.EDhApiLevelType;
|
import com.seibel.distanthorizons.api.enums.worldGeneration.EDhApiLevelType;
|
||||||
import com.seibel.distanthorizons.api.interfaces.render.IDhApiCustomRenderRegister;
|
import com.seibel.distanthorizons.api.interfaces.render.IDhApiCustomRenderRegister;
|
||||||
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.ClientBlockStateColorCache;
|
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.core.dataObjects.fullData.sources.FullDataSourceV2;
|
||||||
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.level.IServerKeyedClientLevel;
|
import com.seibel.distanthorizons.core.level.IServerKeyedClientLevel;
|
||||||
@@ -24,16 +24,19 @@ 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.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 com.seibel.distanthorizons.core.logging.DhLogger;
|
||||||
import net.minecraft.world.phys.Vec3;
|
|
||||||
import org.apache.logging.log4j.Logger;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.lang.ref.WeakReference;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.WeakHashMap;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
#if MC_VER <= MC_1_20_4
|
#if MC_VER <= MC_1_20_4
|
||||||
import net.minecraft.world.level.chunk.ChunkStatus;
|
import net.minecraft.world.level.chunk.ChunkStatus;
|
||||||
@@ -42,25 +45,33 @@ import net.minecraft.world.level.chunk.status.ChunkStatus;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if MC_VER < MC_1_21_3
|
#if MC_VER < MC_1_21_3
|
||||||
|
import net.minecraft.world.phys.Vec3;
|
||||||
#else
|
#else
|
||||||
import com.seibel.distanthorizons.core.util.ColorUtil;
|
import com.seibel.distanthorizons.core.util.ColorUtil;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
public class ClientLevelWrapper implements IClientLevelWrapper
|
public class ClientLevelWrapper implements IClientLevelWrapper
|
||||||
{
|
{
|
||||||
private static final Logger LOGGER = DhLoggerBuilder.getLogger(ClientLevelWrapper.class.getSimpleName());
|
private static final DhLogger LOGGER = new DhLoggerBuilder().build();
|
||||||
private static final ConcurrentHashMap<ClientLevel, ClientLevelWrapper> LEVEL_WRAPPER_BY_CLIENT_LEVEL = new ConcurrentHashMap<>(); // TODO can leak
|
/**
|
||||||
|
* weak references are to prevent rare issues
|
||||||
|
* where, upon world closure, some levels aren't shutdown/removed properly
|
||||||
|
* and/or for servers were the level object isn't consistent
|
||||||
|
*/
|
||||||
|
private static final Map<ClientLevel, WeakReference<ClientLevelWrapper>> LEVEL_WRAPPER_REF_BY_CLIENT_LEVEL = Collections.synchronizedMap(new WeakHashMap<>());
|
||||||
private static final IKeyedClientLevelManager KEYED_CLIENT_LEVEL_MANAGER = SingletonInjector.INSTANCE.get(IKeyedClientLevelManager.class);
|
private static final IKeyedClientLevelManager KEYED_CLIENT_LEVEL_MANAGER = SingletonInjector.INSTANCE.get(IKeyedClientLevelManager.class);
|
||||||
|
|
||||||
private static final Minecraft MINECRAFT = Minecraft.getInstance();
|
private static final Minecraft MINECRAFT = Minecraft.getInstance();
|
||||||
|
|
||||||
private final ClientLevel level;
|
private final ClientLevel level;
|
||||||
private final ConcurrentHashMap<BlockState, ClientBlockStateColorCache> blockCache = new ConcurrentHashMap<>();
|
private final ConcurrentHashMap<BlockState, ClientBlockStateColorCache> blockColorCacheByBlockState = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
/** cached method reference to reduce GC overhead */
|
||||||
|
private final Function<BlockState, ClientBlockStateColorCache> createCachedBlockColorCacheFunc = (blockState) -> new ClientBlockStateColorCache(blockState, this);
|
||||||
|
|
||||||
|
|
||||||
private BlockStateWrapper dirtBlockWrapper;
|
private BlockStateWrapper dirtBlockWrapper;
|
||||||
private BiomeWrapper plainsBiomeWrapper;
|
private IDhLevel dhLevel;
|
||||||
@Deprecated // TODO circular references are bad
|
|
||||||
private IDhLevel parentDhLevel;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -72,10 +83,33 @@ public class ClientLevelWrapper implements IClientLevelWrapper
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
//===============//
|
//==================//
|
||||||
// wrapper logic //
|
// instance methods //
|
||||||
//===============//
|
//==================//
|
||||||
|
|
||||||
|
/**
|
||||||
|
* can be used when speed is important and the same level is likely to be passed in,
|
||||||
|
* IE rendering.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
public static IClientLevelWrapper getWrapperIfDifferent(@Nullable IClientLevelWrapper levelWrapper, @NotNull ClientLevel level)
|
||||||
|
{
|
||||||
|
if (KEYED_CLIENT_LEVEL_MANAGER.isEnabled() && KEYED_CLIENT_LEVEL_MANAGER.getServerKeyedLevel() != levelWrapper)
|
||||||
|
{
|
||||||
|
return getWrapper(level);
|
||||||
|
}
|
||||||
|
|
||||||
|
ClientLevelWrapper clientLevelWrapper = (ClientLevelWrapper)levelWrapper;
|
||||||
|
if (clientLevelWrapper == null
|
||||||
|
|| clientLevelWrapper.level != level)
|
||||||
|
{
|
||||||
|
return getWrapper(level);
|
||||||
|
}
|
||||||
|
|
||||||
|
return clientLevelWrapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
public static IClientLevelWrapper getWrapper(@NotNull ClientLevel level) { return getWrapper(level, false); }
|
public static IClientLevelWrapper getWrapper(@NotNull ClientLevel level) { return getWrapper(level, false); }
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@@ -96,7 +130,31 @@ public class ClientLevelWrapper implements IClientLevelWrapper
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return LEVEL_WRAPPER_BY_CLIENT_LEVEL.computeIfAbsent(level, ClientLevelWrapper::new);
|
|
||||||
|
WeakReference<ClientLevelWrapper> levelRef = LEVEL_WRAPPER_REF_BY_CLIENT_LEVEL.get(level);
|
||||||
|
if (levelRef != null)
|
||||||
|
{
|
||||||
|
ClientLevelWrapper levelWrapper = levelRef.get();
|
||||||
|
if (levelWrapper != null)
|
||||||
|
{
|
||||||
|
return levelWrapper;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return LEVEL_WRAPPER_REF_BY_CLIENT_LEVEL.compute(level, (newLevel, newLevelRef) ->
|
||||||
|
{
|
||||||
|
if (newLevelRef != null)
|
||||||
|
{
|
||||||
|
ClientLevelWrapper oldLevelWrapper = newLevelRef.get();
|
||||||
|
if (oldLevelWrapper != null)
|
||||||
|
{
|
||||||
|
return newLevelRef;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new WeakReference<>(new ClientLevelWrapper(newLevel));
|
||||||
|
}).get();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@@ -105,13 +163,17 @@ public class ClientLevelWrapper implements IClientLevelWrapper
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
// this method only makes sense if we are running a single-player server
|
||||||
|
if (MINECRAFT.getSingleplayerServer() == null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
Iterable<ServerLevel> serverLevels = MINECRAFT.getSingleplayerServer().getAllLevels();
|
Iterable<ServerLevel> serverLevels = MINECRAFT.getSingleplayerServer().getAllLevels();
|
||||||
|
|
||||||
// attempt to find the server level with the same dimension type
|
// attempt to find the server level with the same dimension type
|
||||||
// TODO this assumes only one level per dimension type, the SubDimensionLevelMatcher will need to be added for supporting multiple levels per dimension
|
// Note: this assumes only one level per dimension type, multiverse servers may not behave correctly
|
||||||
ServerLevelWrapper foundLevelWrapper = null;
|
ServerLevelWrapper foundLevelWrapper = null;
|
||||||
|
|
||||||
// TODO: Surely there is a more efficient way to write this code
|
|
||||||
for (ServerLevel serverLevel : serverLevels)
|
for (ServerLevel serverLevel : serverLevels)
|
||||||
{
|
{
|
||||||
if (serverLevel.dimension() == this.level.dimension())
|
if (serverLevel.dimension() == this.level.dimension())
|
||||||
@@ -137,15 +199,20 @@ public class ClientLevelWrapper implements IClientLevelWrapper
|
|||||||
//====================//
|
//====================//
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getBlockColor(DhBlockPos pos, IBiomeWrapper biome, IBlockStateWrapper blockWrapper)
|
public int getBlockColor(DhBlockPos blockPos, IBiomeWrapper biome, FullDataSourceV2 fullDataSource, IBlockStateWrapper blockWrapper)
|
||||||
{
|
{
|
||||||
ClientBlockStateColorCache blockColorCache = this.blockCache.computeIfAbsent(
|
ClientBlockStateColorCache blockColorCache = this.blockColorCacheByBlockState.get(((BlockStateWrapper) blockWrapper).blockState);
|
||||||
((BlockStateWrapper) blockWrapper).blockState,
|
if (blockColorCache == null)
|
||||||
(block) -> new ClientBlockStateColorCache(block, this));
|
{
|
||||||
|
blockColorCache = this.blockColorCacheByBlockState.computeIfAbsent(
|
||||||
|
((BlockStateWrapper) blockWrapper).blockState,
|
||||||
|
this.createCachedBlockColorCacheFunc);
|
||||||
|
}
|
||||||
|
|
||||||
return blockColorCache.getColor((BiomeWrapper) biome, pos);
|
return blockColorCache.getColor((BiomeWrapper) biome, fullDataSource, blockPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getDirtBlockColor()
|
public int getDirtBlockColor()
|
||||||
{
|
{
|
||||||
@@ -163,31 +230,11 @@ public class ClientLevelWrapper implements IClientLevelWrapper
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.getBlockColor(DhBlockPos.ZERO,BiomeWrapper.EMPTY_WRAPPER, this.dirtBlockWrapper);
|
return this.getBlockColor(DhBlockPos.ZERO, BiomeWrapper.EMPTY_WRAPPER, null, this.dirtBlockWrapper);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void clearBlockColorCache() { this.blockCache.clear(); }
|
public void clearBlockColorCache() { this.blockColorCacheByBlockState.clear(); }
|
||||||
|
|
||||||
@Override
|
|
||||||
public IBiomeWrapper getPlainsBiomeWrapper()
|
|
||||||
{
|
|
||||||
if (this.plainsBiomeWrapper == null)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
this.plainsBiomeWrapper = (BiomeWrapper) BiomeWrapper.deserialize(BiomeWrapper.PLAINS_RESOURCE_LOCATION_STRING, this);
|
|
||||||
}
|
|
||||||
catch (IOException e)
|
|
||||||
{
|
|
||||||
// shouldn't happen, but just in case
|
|
||||||
LOGGER.warn("Unable to get planes biome with resource location ["+BiomeWrapper.PLAINS_RESOURCE_LOCATION_STRING+"] with level ["+this+"].", e);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.plainsBiomeWrapper;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IDimensionTypeWrapper getDimensionType() { return DimensionTypeWrapper.getDimensionTypeWrapper(this.level.dimensionType()); }
|
public IDimensionTypeWrapper getDimensionType() { return DimensionTypeWrapper.getDimensionTypeWrapper(this.level.dimensionType()); }
|
||||||
@@ -245,39 +292,25 @@ public class ClientLevelWrapper implements IClientLevelWrapper
|
|||||||
return new ChunkWrapper(chunk, this);
|
return new ChunkWrapper(chunk, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean hasChunkLoaded(int chunkX, int chunkZ)
|
|
||||||
{
|
|
||||||
ChunkSource source = this.level.getChunkSource();
|
|
||||||
return source.hasChunk(chunkX, chunkZ);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public IBlockStateWrapper getBlockState(DhBlockPos pos)
|
|
||||||
{ return BlockStateWrapper.fromBlockState(this.level.getBlockState(McObjectConverter.Convert(pos)), this); }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public IBiomeWrapper getBiome(DhBlockPos pos) { return BiomeWrapper.getBiomeWrapper(this.level.getBiome(McObjectConverter.Convert(pos)), this); }
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ClientLevel getWrappedMcObject() { return this.level; }
|
public ClientLevel getWrappedMcObject() { return this.level; }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onUnload()
|
public void onUnload()
|
||||||
{
|
{
|
||||||
LEVEL_WRAPPER_BY_CLIENT_LEVEL.remove(this.level);
|
LEVEL_WRAPPER_REF_BY_CLIENT_LEVEL.remove(this.level);
|
||||||
this.parentDhLevel = null;
|
this.dhLevel = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public File getDhSaveFolder()
|
public File getDhSaveFolder()
|
||||||
{
|
{
|
||||||
if (this.parentDhLevel == null)
|
if (this.dhLevel == null)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.parentDhLevel.getSaveStructure().getSaveFolder(this);
|
return this.dhLevel.getSaveStructure().getSaveFolder(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -288,17 +321,19 @@ public class ClientLevelWrapper implements IClientLevelWrapper
|
|||||||
//===================//
|
//===================//
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setParentLevel(IDhLevel parentLevel) { this.parentDhLevel = parentLevel; }
|
public void setDhLevel(IDhLevel dhLevel) { this.dhLevel = dhLevel; }
|
||||||
|
@Override
|
||||||
|
public IDhLevel getDhLevel() { return this.dhLevel; }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IDhApiCustomRenderRegister getRenderRegister()
|
public IDhApiCustomRenderRegister getRenderRegister()
|
||||||
{
|
{
|
||||||
if (this.parentDhLevel == null)
|
if (this.dhLevel == null)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.parentDhLevel.getGenericRenderer();
|
return this.dhLevel.getGenericRenderer();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
+108
-54
@@ -20,24 +20,26 @@
|
|||||||
package com.seibel.distanthorizons.common.wrappers.world;
|
package com.seibel.distanthorizons.common.wrappers.world;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.lang.ref.WeakReference;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.WeakHashMap;
|
||||||
|
|
||||||
import com.seibel.distanthorizons.api.enums.worldGeneration.EDhApiLevelType;
|
import com.seibel.distanthorizons.api.enums.worldGeneration.EDhApiLevelType;
|
||||||
import com.seibel.distanthorizons.api.interfaces.render.IDhApiCustomRenderRegister;
|
import com.seibel.distanthorizons.api.interfaces.render.IDhApiCustomRenderRegister;
|
||||||
import com.seibel.distanthorizons.common.wrappers.McObjectConverter;
|
|
||||||
import com.seibel.distanthorizons.common.wrappers.block.BiomeWrapper;
|
|
||||||
import com.seibel.distanthorizons.common.wrappers.block.BlockStateWrapper;
|
|
||||||
import com.seibel.distanthorizons.common.wrappers.chunk.ChunkWrapper;
|
import com.seibel.distanthorizons.common.wrappers.chunk.ChunkWrapper;
|
||||||
|
import com.seibel.distanthorizons.core.api.internal.SharedApi;
|
||||||
|
import com.seibel.distanthorizons.core.config.Config;
|
||||||
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.blockPos.DhBlockPos;
|
import com.seibel.distanthorizons.core.network.messages.base.LevelInitMessage;
|
||||||
import com.seibel.distanthorizons.core.pos.DhChunkPos;
|
import com.seibel.distanthorizons.core.pos.DhChunkPos;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.block.IBlockStateWrapper;
|
import com.seibel.distanthorizons.core.world.EWorldEnvironment;
|
||||||
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.IServerLevelWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IServerLevelWrapper;
|
||||||
import net.minecraft.server.level.ServerLevel;
|
import net.minecraft.server.level.ServerLevel;
|
||||||
|
import net.minecraft.world.level.Level;
|
||||||
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;
|
||||||
|
|
||||||
@@ -47,21 +49,26 @@ import net.minecraft.world.level.chunk.ChunkStatus;
|
|||||||
import net.minecraft.world.level.chunk.status.ChunkStatus;
|
import net.minecraft.world.level.chunk.status.ChunkStatus;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if MC_VER < MC_1_21_3
|
import com.seibel.distanthorizons.core.logging.DhLogger;
|
||||||
#else
|
import org.jetbrains.annotations.Nullable;
|
||||||
import java.nio.file.Path;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
import org.apache.logging.log4j.Logger;
|
|
||||||
|
|
||||||
public class ServerLevelWrapper implements IServerLevelWrapper
|
public class ServerLevelWrapper implements IServerLevelWrapper
|
||||||
{
|
{
|
||||||
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
|
private static final DhLogger LOGGER = new DhLoggerBuilder().build();
|
||||||
private static final ConcurrentHashMap<ServerLevel, ServerLevelWrapper> LEVEL_WRAPPER_BY_SERVER_LEVEL = new ConcurrentHashMap<>();
|
/**
|
||||||
|
* weak references are to prevent rare issues
|
||||||
|
* where, upon world closure, some levels aren't shutdown/removed properly
|
||||||
|
*/
|
||||||
|
private static final Map<ServerLevel, WeakReference<ServerLevelWrapper>> LEVEL_WRAPPER_REF_BY_SERVER_LEVEL = Collections.synchronizedMap(new WeakHashMap<>());
|
||||||
|
|
||||||
private final ServerLevel level;
|
private final ServerLevel level;
|
||||||
@Deprecated // TODO circular references are bad
|
private IDhLevel dhLevel;
|
||||||
private IDhLevel parentDhLevel;
|
|
||||||
|
/**
|
||||||
|
* this name is cached to prevent issues during shutdown where
|
||||||
|
* the server variables needed may no longer be available.
|
||||||
|
*/
|
||||||
|
private final String KeyedLevelDimensionName;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -70,15 +77,33 @@ public class ServerLevelWrapper implements IServerLevelWrapper
|
|||||||
//==============//
|
//==============//
|
||||||
|
|
||||||
public static ServerLevelWrapper getWrapper(ServerLevel level)
|
public static ServerLevelWrapper getWrapper(ServerLevel level)
|
||||||
{ return LEVEL_WRAPPER_BY_SERVER_LEVEL.computeIfAbsent(level, ServerLevelWrapper::new); }
|
{
|
||||||
|
return LEVEL_WRAPPER_REF_BY_SERVER_LEVEL.compute(level, (newLevel, levelRef) ->
|
||||||
|
{
|
||||||
|
if (levelRef != null)
|
||||||
|
{
|
||||||
|
ServerLevelWrapper oldLevelWrapper = levelRef.get();
|
||||||
|
if (oldLevelWrapper != null)
|
||||||
|
{
|
||||||
|
return levelRef;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new WeakReference<>(new ServerLevelWrapper(newLevel));
|
||||||
|
}).get();
|
||||||
|
}
|
||||||
|
|
||||||
public ServerLevelWrapper(ServerLevel level) { this.level = level; }
|
public ServerLevelWrapper(ServerLevel level)
|
||||||
|
{
|
||||||
|
this.level = level;
|
||||||
|
this.KeyedLevelDimensionName = this.createKeyedLevelDimensionName();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//=========//
|
//==================//
|
||||||
// methods //
|
// instance methods //
|
||||||
//=========//
|
//==================//
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public File getMcSaveFolder()
|
public File getMcSaveFolder()
|
||||||
@@ -91,14 +116,60 @@ public class ServerLevelWrapper implements IServerLevelWrapper
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getWorldFolderName()
|
public String getKeyedLevelDimensionName() { return this.KeyedLevelDimensionName; }
|
||||||
|
|
||||||
|
private String createKeyedLevelDimensionName()
|
||||||
{
|
{
|
||||||
#if MC_VER >= MC_1_17_1
|
String dimensionName = this.getDhIdentifier();
|
||||||
return this.level.getServer().getWorldScreenshotFile().get().getParent().getFileName().toString();
|
|
||||||
#else // <= 1.16.5
|
if (Config.Server.sendLevelKeys.get())
|
||||||
return this.level.getServer().getWorldScreenshotFile().getParentFile().getName();
|
{
|
||||||
#endif
|
String levelKeyPrefix = Config.Server.levelKeyPrefix.get();
|
||||||
|
|
||||||
|
if (SharedApi.getEnvironment() == EWorldEnvironment.CLIENT_SERVER)
|
||||||
|
{
|
||||||
|
String cleanWorldFolderName = this.getWorldFolderName()
|
||||||
|
.replaceAll("[^" + LevelInitMessage.ALLOWED_CHARS_REGEX + " ]", "")
|
||||||
|
.replaceAll(" ", "_");
|
||||||
|
|
||||||
|
levelKeyPrefix += (!levelKeyPrefix.isEmpty() ? "_" : "") + cleanWorldFolderName
|
||||||
|
+ "_" + this.getHashedSeedEncoded();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (levelKeyPrefix.isEmpty())
|
||||||
|
{
|
||||||
|
levelKeyPrefix = this.getHashedSeedEncoded();
|
||||||
|
}
|
||||||
|
|
||||||
|
String mainPart = "@" + dimensionName;
|
||||||
|
|
||||||
|
return levelKeyPrefix.substring(0, Math.min(
|
||||||
|
LevelInitMessage.MAX_LENGTH - mainPart.length(),
|
||||||
|
levelKeyPrefix.length()
|
||||||
|
)) + mainPart;
|
||||||
|
}
|
||||||
|
|
||||||
|
return dimensionName;
|
||||||
}
|
}
|
||||||
|
private String getWorldFolderName()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// We use the overworld since it's the only dimension that is stored in the server root folder
|
||||||
|
|
||||||
|
#if MC_VER >= MC_1_21_3
|
||||||
|
return this.level.getServer().getLevel(Level.OVERWORLD).getChunkSource().getDataStorage().dataFolder.getParent().getFileName().toString();
|
||||||
|
#else // <= 1.21.3
|
||||||
|
return this.level.getServer().getLevel(Level.OVERWORLD).getChunkSource().getDataStorage().dataFolder.getParentFile().getName();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
LOGGER.warn("Unable to get world folder name. LODs may not load or save correctly. Error: ["+e.getMessage()+"].", e);
|
||||||
|
return "unknown_world";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DimensionTypeWrapper getDimensionType() { return DimensionTypeWrapper.getDimensionTypeWrapper(this.level.dimensionType()); }
|
public DimensionTypeWrapper getDimensionType() { return DimensionTypeWrapper.getDimensionTypeWrapper(this.level.dimensionType()); }
|
||||||
@@ -155,56 +226,39 @@ public class ServerLevelWrapper implements IServerLevelWrapper
|
|||||||
return new ChunkWrapper(chunk, this);
|
return new ChunkWrapper(chunk, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean hasChunkLoaded(int chunkX, int chunkZ)
|
|
||||||
{
|
|
||||||
// world.hasChunk(chunkX, chunkZ); THIS DOES NOT WORK FOR CLIENT LEVEL CAUSE MOJANG ALWAYS RETURN TRUE FOR THAT!
|
|
||||||
ChunkSource source = this.level.getChunkSource();
|
|
||||||
return source.hasChunk(chunkX, chunkZ);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public IBlockStateWrapper getBlockState(DhBlockPos pos)
|
|
||||||
{
|
|
||||||
return BlockStateWrapper.fromBlockState(this.level.getBlockState(McObjectConverter.Convert(pos)), this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public IBiomeWrapper getBiome(DhBlockPos pos)
|
|
||||||
{
|
|
||||||
return BiomeWrapper.getBiomeWrapper(this.level.getBiome(McObjectConverter.Convert(pos)), this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ServerLevel getWrappedMcObject() { return this.level; }
|
public ServerLevel getWrappedMcObject() { return this.level; }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onUnload() { LEVEL_WRAPPER_BY_SERVER_LEVEL.remove(this.level); }
|
public void onUnload() { LEVEL_WRAPPER_REF_BY_SERVER_LEVEL.remove(this.level); }
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setParentLevel(IDhLevel parentLevel) { this.parentDhLevel = parentLevel; }
|
public void setDhLevel(IDhLevel dhLevel) { this.dhLevel = dhLevel; }
|
||||||
|
@Override
|
||||||
|
@Nullable
|
||||||
|
public IDhLevel getDhLevel() { return this.dhLevel; }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IDhApiCustomRenderRegister getRenderRegister()
|
public IDhApiCustomRenderRegister getRenderRegister()
|
||||||
{
|
{
|
||||||
if (this.parentDhLevel == null)
|
if (this.dhLevel == null)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.parentDhLevel.getGenericRenderer();
|
return this.dhLevel.getGenericRenderer();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public File getDhSaveFolder()
|
public File getDhSaveFolder()
|
||||||
{
|
{
|
||||||
if (this.parentDhLevel == null)
|
if (this.dhLevel == null)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.parentDhLevel.getSaveStructure().getSaveFolder(this);
|
return this.dhLevel.getSaveStructure().getSaveFolder(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+106
-61
@@ -29,8 +29,8 @@ import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
|||||||
import com.seibel.distanthorizons.core.generation.DhLightingEngine;
|
import com.seibel.distanthorizons.core.generation.DhLightingEngine;
|
||||||
import com.seibel.distanthorizons.core.level.IDhServerLevel;
|
import com.seibel.distanthorizons.core.level.IDhServerLevel;
|
||||||
import com.seibel.distanthorizons.core.config.Config;
|
import com.seibel.distanthorizons.core.config.Config;
|
||||||
import com.seibel.distanthorizons.core.logging.ConfigBasedLogger;
|
import com.seibel.distanthorizons.core.logging.DhLogger;
|
||||||
import com.seibel.distanthorizons.core.logging.ConfigBasedSpamLogger;
|
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||||
import com.seibel.distanthorizons.core.pos.DhChunkPos;
|
import com.seibel.distanthorizons.core.pos.DhChunkPos;
|
||||||
import com.seibel.distanthorizons.core.util.objects.EventTimer;
|
import com.seibel.distanthorizons.core.util.objects.EventTimer;
|
||||||
import com.seibel.distanthorizons.core.util.LodUtil;
|
import com.seibel.distanthorizons.core.util.LodUtil;
|
||||||
@@ -42,6 +42,8 @@ import com.seibel.distanthorizons.core.wrapperInterfaces.worldGeneration.Abstrac
|
|||||||
import com.seibel.distanthorizons.common.wrappers.chunk.ChunkWrapper;
|
import com.seibel.distanthorizons.common.wrappers.chunk.ChunkWrapper;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.nio.channels.ClosedByInterruptException;
|
||||||
|
import java.nio.channels.ClosedChannelException;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.*;
|
import java.util.concurrent.*;
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
@@ -50,6 +52,9 @@ import java.util.function.Function;
|
|||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
import java.util.stream.StreamSupport;
|
import java.util.stream.StreamSupport;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import com.seibel.distanthorizons.common.wrappers.DependencySetupDoneCheck;
|
import com.seibel.distanthorizons.common.wrappers.DependencySetupDoneCheck;
|
||||||
import com.seibel.distanthorizons.common.wrappers.worldGeneration.step.StepBiomes;
|
import com.seibel.distanthorizons.common.wrappers.worldGeneration.step.StepBiomes;
|
||||||
import com.seibel.distanthorizons.common.wrappers.worldGeneration.step.StepFeatures;
|
import com.seibel.distanthorizons.common.wrappers.worldGeneration.step.StepFeatures;
|
||||||
@@ -60,10 +65,7 @@ import com.seibel.distanthorizons.common.wrappers.worldGeneration.step.StepSurfa
|
|||||||
|
|
||||||
import net.minecraft.server.level.*;
|
import net.minecraft.server.level.*;
|
||||||
import net.minecraft.world.level.ChunkPos;
|
import net.minecraft.world.level.ChunkPos;
|
||||||
import net.minecraft.world.level.chunk.ChunkAccess;
|
import net.minecraft.world.level.chunk.*;
|
||||||
import net.minecraft.world.level.chunk.ChunkGenerator;
|
|
||||||
import net.minecraft.world.level.chunk.ProtoChunk;
|
|
||||||
import net.minecraft.world.level.chunk.UpgradeData;
|
|
||||||
import net.minecraft.world.level.chunk.storage.IOWorker;
|
import net.minecraft.world.level.chunk.storage.IOWorker;
|
||||||
import net.minecraft.world.level.chunk.storage.RegionFileStorage;
|
import net.minecraft.world.level.chunk.storage.RegionFileStorage;
|
||||||
import net.minecraft.world.level.levelgen.DebugLevelSource;
|
import net.minecraft.world.level.levelgen.DebugLevelSource;
|
||||||
@@ -71,21 +73,21 @@ import net.minecraft.world.level.levelgen.FlatLevelSource;
|
|||||||
import net.minecraft.world.level.levelgen.Heightmap;
|
import net.minecraft.world.level.levelgen.Heightmap;
|
||||||
import net.minecraft.world.level.levelgen.NoiseBasedChunkGenerator;
|
import net.minecraft.world.level.levelgen.NoiseBasedChunkGenerator;
|
||||||
import net.minecraft.nbt.CompoundTag;
|
import net.minecraft.nbt.CompoundTag;
|
||||||
import org.apache.logging.log4j.LogManager;
|
|
||||||
|
|
||||||
#if MC_VER >= MC_1_19_4
|
#if MC_VER <= MC_1_17_1
|
||||||
import net.minecraft.core.registries.Registries;
|
#elif MC_VER <= MC_1_19_2
|
||||||
#else
|
|
||||||
import net.minecraft.core.Registry;
|
import net.minecraft.core.Registry;
|
||||||
|
#elif MC_VER <= MC_1_19_4
|
||||||
|
import net.minecraft.core.registries.Registries;
|
||||||
|
#elif MC_VER < MC_1_21_3
|
||||||
|
import net.minecraft.core.registries.Registries;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#if MC_VER <= MC_1_20_4
|
#if MC_VER <= MC_1_20_4
|
||||||
import net.minecraft.world.level.chunk.ChunkStatus;
|
import net.minecraft.world.level.chunk.ChunkStatus;
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
#else
|
#else
|
||||||
import net.minecraft.world.level.chunk.status.ChunkStatus;
|
import net.minecraft.world.level.chunk.status.ChunkStatus;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -103,22 +105,32 @@ Lod Generation: 0.269023348s
|
|||||||
*/
|
*/
|
||||||
public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnvironmentWrapper
|
public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnvironmentWrapper
|
||||||
{
|
{
|
||||||
public static final ConfigBasedSpamLogger PREF_LOGGER =
|
public static final DhLogger PREF_LOGGER = new DhLoggerBuilder()
|
||||||
new ConfigBasedSpamLogger(LogManager.getLogger("LodWorldGen"),
|
.name("LOD World Gen")
|
||||||
() -> Config.Common.Logging.logWorldGenPerformance.get(), 1);
|
.fileLevelConfig(Config.Common.Logging.logWorldGenPerformanceToFile)
|
||||||
public static final ConfigBasedLogger EVENT_LOGGER =
|
.maxCountPerSecond(1)
|
||||||
new ConfigBasedLogger(LogManager.getLogger("LodWorldGen"),
|
.build();
|
||||||
() -> Config.Common.Logging.logWorldGenEvent.get());
|
public static final DhLogger EVENT_LOGGER = new DhLoggerBuilder()
|
||||||
public static final ConfigBasedLogger LOAD_LOGGER =
|
.name("LOD World Gen")
|
||||||
new ConfigBasedLogger(LogManager.getLogger("LodWorldGen"),
|
.fileLevelConfig(Config.Common.Logging.logWorldGenEventToFile)
|
||||||
() -> Config.Common.Logging.logWorldGenLoadEvent.get());
|
.build();
|
||||||
|
public static final DhLogger CHUNK_LOAD_LOGGER = new DhLoggerBuilder()
|
||||||
|
.name("LOD World Gen")
|
||||||
|
.fileLevelConfig(Config.Common.Logging.logWorldGenChunkLoadEventToFile)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
#if MC_VER < MC_1_21_5
|
||||||
private static final TicketType<ChunkPos> DH_SERVER_GEN_TICKET = TicketType.create("dh_server_gen_ticket", Comparator.comparingLong(ChunkPos::toLong));
|
private static final TicketType<ChunkPos> DH_SERVER_GEN_TICKET = TicketType.create("dh_server_gen_ticket", Comparator.comparingLong(ChunkPos::toLong));
|
||||||
|
#elif MC_VER < MC_1_21_9
|
||||||
|
private static final TicketType DH_SERVER_GEN_TICKET = new TicketType(/* timeout, 0 = disabled*/0L, /* persist */ false, TicketType.TicketUse.LOADING);
|
||||||
|
#else
|
||||||
|
private static final TicketType DH_SERVER_GEN_TICKET = new TicketType(/* timeout, 0 = disabled*/0L, /* flags */TicketType.FLAG_LOADING);
|
||||||
|
#endif
|
||||||
|
|
||||||
private static final IModChecker MOD_CHECKER = SingletonInjector.INSTANCE.get(IModChecker.class);
|
private static final IModChecker MOD_CHECKER = SingletonInjector.INSTANCE.get(IModChecker.class);
|
||||||
|
|
||||||
|
|
||||||
private final IDhServerLevel serverlevel;
|
private final IDhServerLevel serverLevel;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* will be true if C2ME is installed (since they require us to
|
* will be true if C2ME is installed (since they require us to
|
||||||
@@ -170,6 +182,7 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
|
|||||||
// constructors //
|
// constructors //
|
||||||
//==============//
|
//==============//
|
||||||
|
|
||||||
|
@NotNull
|
||||||
public static final ImmutableMap<EDhApiWorldGenerationStep, Integer> WORLD_GEN_CHUNK_BORDER_NEEDED_BY_GEN_STEP;
|
public static final ImmutableMap<EDhApiWorldGenerationStep, Integer> WORLD_GEN_CHUNK_BORDER_NEEDED_BY_GEN_STEP;
|
||||||
public static final int MAX_WORLD_GEN_CHUNK_BORDER_NEEDED;
|
public static final int MAX_WORLD_GEN_CHUNK_BORDER_NEEDED;
|
||||||
|
|
||||||
@@ -201,23 +214,24 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
|
|||||||
builder.put(EDhApiWorldGenerationStep.LIGHT, 0);
|
builder.put(EDhApiWorldGenerationStep.LIGHT, 0);
|
||||||
WORLD_GEN_CHUNK_BORDER_NEEDED_BY_GEN_STEP = builder.build();
|
WORLD_GEN_CHUNK_BORDER_NEEDED_BY_GEN_STEP = builder.build();
|
||||||
|
|
||||||
// TODO this is a test to see if the additional boarder is actually necessary or not.
|
// in James' testing as of 2025-09-13 a border here of 2
|
||||||
// If world generators end up having infinite loops or other unexplained issues,
|
// and a getChunkPosToGenerateStream() radius of 14 provided more accurate
|
||||||
// this should be set back to the commented out logic below
|
// structure generation, however it also caused extreme server lag
|
||||||
|
// a border of 0 here and a getChunkPosToGenerateStream() radius of 8 provided
|
||||||
|
// good-enough structure generation while not lagging the server
|
||||||
MAX_WORLD_GEN_CHUNK_BORDER_NEEDED = 0;
|
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)
|
||||||
{
|
{
|
||||||
super(serverlevel);
|
super(serverLevel);
|
||||||
this.serverlevel = serverlevel;
|
this.serverLevel = serverLevel;
|
||||||
|
|
||||||
EVENT_LOGGER.info("================WORLD_GEN_STEP_INITING=============");
|
EVENT_LOGGER.info("================WORLD_GEN_STEP_INITING=============");
|
||||||
|
|
||||||
serverlevel.getServerLevelWrapper().getDimensionType();
|
serverLevel.getServerLevelWrapper().getDimensionType();
|
||||||
|
|
||||||
ChunkGenerator generator = ((ServerLevelWrapper) (serverlevel.getServerLevelWrapper())).getLevel().getChunkSource().getGenerator();
|
ChunkGenerator generator = ((ServerLevelWrapper) (serverLevel.getServerLevelWrapper())).getLevel().getChunkSource().getGenerator();
|
||||||
if (!(generator instanceof NoiseBasedChunkGenerator ||
|
if (!(generator instanceof NoiseBasedChunkGenerator ||
|
||||||
generator instanceof DebugLevelSource ||
|
generator instanceof DebugLevelSource ||
|
||||||
generator instanceof FlatLevelSource))
|
generator instanceof FlatLevelSource))
|
||||||
@@ -245,7 +259,7 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
|
|||||||
this.pullExistingChunkUsingMcAsyncMethod = true;
|
this.pullExistingChunkUsingMcAsyncMethod = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.params = new GlobalParameters(serverlevel);
|
this.params = new GlobalParameters(serverLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -305,7 +319,7 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
event.future.get(); // Should throw exception
|
event.future.get(); // Should throw exception
|
||||||
LodUtil.assertNotReach();
|
LodUtil.assertNotReach("Exceptionally completed world gen Future should have thrown an exception.");
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
@@ -383,7 +397,9 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
|
|||||||
CompletableFuture.allOf(readFutures).join();
|
CompletableFuture.allOf(readFutures).join();
|
||||||
|
|
||||||
// future chain for generation
|
// future chain for generation
|
||||||
return CompletableFuture.runAsync(() ->
|
return CompletableFuture.runAsync(() ->
|
||||||
|
{
|
||||||
|
try
|
||||||
{
|
{
|
||||||
// offset 1 chunk in both X and Z direction so we can generate an even number of chunks wide
|
// offset 1 chunk in both X and Z direction so we can generate an even number of chunks wide
|
||||||
// while still submitting an odd number width to MC's internal generators
|
// while still submitting an odd number width to MC's internal generators
|
||||||
@@ -406,10 +422,10 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
|
|||||||
int centerZ = refPosZ + radius + zOffset;
|
int centerZ = refPosZ + radius + zOffset;
|
||||||
|
|
||||||
// get/create the list of chunks we're going to generate
|
// get/create the list of chunks we're going to generate
|
||||||
IEmptyChunkRetrievalFunc fallbackFunc =
|
IEmptyChunkRetrievalFunc fallbackFunc =
|
||||||
(chunkPosX, chunkPosZ) -> Objects.requireNonNull(
|
(chunkPosX, chunkPosZ) -> Objects.requireNonNull(
|
||||||
generatedChunkByDhPos.get(new DhChunkPos(chunkPosX, chunkPosZ)),
|
generatedChunkByDhPos.get(new DhChunkPos(chunkPosX, chunkPosZ)),
|
||||||
() -> String.format("Requested chunk [%d, %d] unavailable during world generation", chunkPosX, chunkPosZ));
|
() -> String.format("Requested chunk [%d, %d] unavailable during world generation", chunkPosX, chunkPosZ));
|
||||||
|
|
||||||
ArrayGridList<ChunkAccess> regionChunks = new ArrayGridList<>(
|
ArrayGridList<ChunkAccess> regionChunks = new ArrayGridList<>(
|
||||||
refSize,
|
refSize,
|
||||||
@@ -431,7 +447,7 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
|
|||||||
// this method shouldn't be necessary since we're passing in a pre-populated
|
// this method shouldn't be necessary since we're passing in a pre-populated
|
||||||
// list of chunks, but just in case
|
// list of chunks, but just in case
|
||||||
fallbackFunc
|
fallbackFunc
|
||||||
);
|
);
|
||||||
lightGetterAdaptor.setRegion(region);
|
lightGetterAdaptor.setRegion(region);
|
||||||
genEvent.threadedParam.makeStructFeat(region, this.params);
|
genEvent.threadedParam.makeStructFeat(region, this.params);
|
||||||
|
|
||||||
@@ -457,7 +473,7 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
|
|||||||
else if (chunk != null)
|
else if (chunk != null)
|
||||||
{
|
{
|
||||||
// wrap the chunk
|
// wrap the chunk
|
||||||
ChunkWrapper chunkWrapper = new ChunkWrapper(chunk, this.serverlevel.getLevelWrapper());
|
ChunkWrapper chunkWrapper = new ChunkWrapper(chunk, this.serverLevel.getLevelWrapper());
|
||||||
chunkWrapperList.set(relX, relZ, chunkWrapper);
|
chunkWrapperList.set(relX, relZ, chunkWrapper);
|
||||||
|
|
||||||
// try setting the wrapper's lighting
|
// try setting the wrapper's lighting
|
||||||
@@ -515,12 +531,17 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
|
|||||||
|
|
||||||
genEvent.timer.complete();
|
genEvent.timer.complete();
|
||||||
genEvent.refreshTimeout();
|
genEvent.refreshTimeout();
|
||||||
if (PREF_LOGGER.canMaybeLog())
|
if (PREF_LOGGER.canLog())
|
||||||
{
|
{
|
||||||
genEvent.threadedParam.perf.recordEvent(genEvent.timer);
|
genEvent.threadedParam.perf.recordEvent(genEvent.timer);
|
||||||
PREF_LOGGER.debugInc(genEvent.timer.toString());
|
PREF_LOGGER.debug(genEvent.timer.toString());
|
||||||
}
|
}
|
||||||
}, executor);
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
EVENT_LOGGER.error("Unexpected error during world gen for min chunk pos ["+genEvent.minPos+"], error: ["+e.getMessage()+"].", e);
|
||||||
|
}
|
||||||
|
}, executor);
|
||||||
}
|
}
|
||||||
/** @param extraRadius in both the positive and negative directions */
|
/** @param extraRadius in both the positive and negative directions */
|
||||||
private static Stream<ChunkPos> getChunkPosToGenerateStream(int genMinX, int genMinZ, int width, int extraRadius)
|
private static Stream<ChunkPos> getChunkPosToGenerateStream(int genMinX, int genMinZ, int width, int extraRadius)
|
||||||
@@ -559,7 +580,7 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
|
|||||||
if (Config.Common.LodBuilding.pullLightingForPregeneratedChunks.get())
|
if (Config.Common.LodBuilding.pullLightingForPregeneratedChunks.get())
|
||||||
{
|
{
|
||||||
// attempt to get chunk lighting
|
// attempt to get chunk lighting
|
||||||
ChunkLoader.CombinedChunkLightStorage combinedLights = ChunkLoader.readLight(newChunk, chunkData);
|
ChunkFileReader.CombinedChunkLightStorage combinedLights = ChunkFileReader.readLight(newChunk, chunkData);
|
||||||
if (combinedLights != null)
|
if (combinedLights != null)
|
||||||
{
|
{
|
||||||
chunkSkyLightingByDhPos.put(dhChunkPos, combinedLights.skyLightStorage);
|
chunkSkyLightingByDhPos.put(dhChunkPos, combinedLights.skyLightStorage);
|
||||||
@@ -662,15 +683,28 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
|
|||||||
actualThrowable = completionException.getCause();
|
actualThrowable = completionException.getCause();
|
||||||
}
|
}
|
||||||
|
|
||||||
LOAD_LOGGER.warn("DistantHorizons: Couldn't load or make chunk ["+chunkPos+"], error: ["+actualThrowable.getMessage()+"].", actualThrowable);
|
// interrupts mean the world generator is being shut down, no need to log that
|
||||||
|
boolean isShutdownException =
|
||||||
|
actualThrowable instanceof InterruptedException
|
||||||
|
|| actualThrowable instanceof ClosedByInterruptException;
|
||||||
|
if (!isShutdownException)
|
||||||
|
{
|
||||||
|
CHUNK_LOAD_LOGGER.warn("DistantHorizons: Couldn't load or make chunk ["+chunkPos+"], error: ["+actualThrowable.getMessage()+"].", actualThrowable);
|
||||||
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
catch (ClosedByInterruptException ignore)
|
||||||
|
{
|
||||||
|
// this just means the world generator is being shut down
|
||||||
|
return CompletableFuture.completedFuture(null);
|
||||||
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
LOAD_LOGGER.warn("DistantHorizons: Couldn't load or make chunk [" + chunkPos + "]. Error: [" + e.getMessage() + "].", e);
|
CHUNK_LOAD_LOGGER.warn("DistantHorizons: Couldn't load or make chunk [" + chunkPos + "]. Error: [" + e.getMessage() + "].", e);
|
||||||
return CompletableFuture.completedFuture(null);
|
return CompletableFuture.completedFuture(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -686,10 +720,10 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
LOAD_LOGGER.debug("DistantHorizons: Loading chunk [" + chunkPos + "] from disk.");
|
CHUNK_LOAD_LOGGER.debug("DistantHorizons: Loading chunk [" + chunkPos + "] from disk.");
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
ChunkAccess chunk = ChunkLoader.read(level, chunkPos, chunkData);
|
ChunkAccess chunk = ChunkFileReader.read(level, chunkPos, chunkData);
|
||||||
if (chunk != null)
|
if (chunk != null)
|
||||||
{
|
{
|
||||||
if (Config.Common.LodBuilding.assumePreExistingChunksAreFinished.get())
|
if (Config.Common.LodBuilding.assumePreExistingChunksAreFinished.get())
|
||||||
@@ -708,7 +742,7 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
|
|||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
LOAD_LOGGER.error(
|
CHUNK_LOAD_LOGGER.error(
|
||||||
"DistantHorizons: couldn't load or make chunk at [" + chunkPos + "]." +
|
"DistantHorizons: couldn't load or make chunk at [" + chunkPos + "]." +
|
||||||
"Please try optimizing your world to fix this issue. \n" +
|
"Please try optimizing your world to fix this issue. \n" +
|
||||||
"World optimization can be done from the singleplayer world selection screen.\n" +
|
"World optimization can be done from the singleplayer world selection screen.\n" +
|
||||||
@@ -731,8 +765,10 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
|
|||||||
return new ProtoChunk(chunkPos, UpgradeData.EMPTY, level, level.registryAccess().registryOrThrow(Registries.BIOME), null);
|
return new ProtoChunk(chunkPos, UpgradeData.EMPTY, level, level.registryAccess().registryOrThrow(Registries.BIOME), null);
|
||||||
#elif MC_VER < MC_1_21_3
|
#elif MC_VER < MC_1_21_3
|
||||||
return new ProtoChunk(chunkPos, UpgradeData.EMPTY, level, level.registryAccess().registryOrThrow(Registries.BIOME), null);
|
return new ProtoChunk(chunkPos, UpgradeData.EMPTY, level, level.registryAccess().registryOrThrow(Registries.BIOME), null);
|
||||||
#else
|
#elif MC_VER < MC_1_21_9
|
||||||
return new ProtoChunk(chunkPos, UpgradeData.EMPTY, level, level.registryAccess().lookupOrThrow(Registries.BIOME), null);
|
return new ProtoChunk(chunkPos, UpgradeData.EMPTY, level, level.registryAccess().lookupOrThrow(Registries.BIOME), null);
|
||||||
|
#else
|
||||||
|
return new ProtoChunk(chunkPos, UpgradeData.EMPTY, level, PalettedContainerFactory.create(level.registryAccess()), null);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -768,12 +804,12 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
|
|||||||
|
|
||||||
if (throwable != null)
|
if (throwable != null)
|
||||||
{
|
{
|
||||||
LOAD_LOGGER.warn("DistantHorizons: Couldn't load chunk [" + chunkPos + "] from server, error: [" + actualThrowable.getMessage() + "].", actualThrowable);
|
CHUNK_LOAD_LOGGER.warn("DistantHorizons: Couldn't load chunk [" + chunkPos + "] from server, error: [" + actualThrowable.getMessage() + "].", actualThrowable);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (chunk != null)
|
if (chunk != null)
|
||||||
{
|
{
|
||||||
ChunkWrapper chunkWrapper = new ChunkWrapper(chunk, this.serverlevel.getLevelWrapper());
|
ChunkWrapper chunkWrapper = new ChunkWrapper(chunk, this.serverLevel.getLevelWrapper());
|
||||||
chunkWrappersByDhPos.put(new DhChunkPos(chunkPos.x, chunkPos.z), chunkWrapper);
|
chunkWrappersByDhPos.put(new DhChunkPos(chunkPos.x, chunkPos.z), chunkWrapper);
|
||||||
}
|
}
|
||||||
}, runnableQueue::add);
|
}, runnableQueue::add);
|
||||||
@@ -787,7 +823,7 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
|
|||||||
{
|
{
|
||||||
// generate chunk lighting using DH's lighting engine
|
// generate chunk lighting using DH's lighting engine
|
||||||
genEvent.timer.nextEvent("light");
|
genEvent.timer.nextEvent("light");
|
||||||
int maxSkyLight = this.serverlevel.getServerLevelWrapper().hasSkyLight() ? LodUtil.MAX_MC_LIGHT : LodUtil.MIN_MC_LIGHT;
|
int maxSkyLight = this.serverLevel.getServerLevelWrapper().hasSkyLight() ? LodUtil.MAX_MC_LIGHT : LodUtil.MIN_MC_LIGHT;
|
||||||
|
|
||||||
ArrayList<IChunkWrapper> generatedChunks = new ArrayList<>(chunkWrappersByDhPos.values());
|
ArrayList<IChunkWrapper> generatedChunks = new ArrayList<>(chunkWrappersByDhPos.values());
|
||||||
for (IChunkWrapper iChunkWrapper : generatedChunks)
|
for (IChunkWrapper iChunkWrapper : generatedChunks)
|
||||||
@@ -800,7 +836,7 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
|
|||||||
DhLightingEngine.INSTANCE.bakeChunkBlockLighting(iChunkWrapper, generatedChunks, maxSkyLight);
|
DhLightingEngine.INSTANCE.bakeChunkBlockLighting(iChunkWrapper, generatedChunks, maxSkyLight);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.serverlevel.updateBeaconBeamsForChunk(iChunkWrapper, generatedChunks);
|
this.serverLevel.updateBeaconBeamsForChunk(iChunkWrapper, generatedChunks);
|
||||||
}
|
}
|
||||||
|
|
||||||
genEvent.timer.nextEvent("cleanup");
|
genEvent.timer.nextEvent("cleanup");
|
||||||
@@ -823,10 +859,10 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
|
|||||||
|
|
||||||
genEvent.timer.complete();
|
genEvent.timer.complete();
|
||||||
genEvent.refreshTimeout();
|
genEvent.refreshTimeout();
|
||||||
if (PREF_LOGGER.canMaybeLog())
|
if (PREF_LOGGER.canLog())
|
||||||
{
|
{
|
||||||
genEvent.threadedParam.perf.recordEvent(genEvent.timer);
|
genEvent.threadedParam.perf.recordEvent(genEvent.timer);
|
||||||
PREF_LOGGER.debugInc(genEvent.timer.toString());
|
PREF_LOGGER.debug(genEvent.timer.toString());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -878,7 +914,11 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
|
|||||||
chunkLevel = generateUpToFeatures ? ChunkLevel.byStatus(ChunkStatus.FEATURES) : 33;
|
chunkLevel = generateUpToFeatures ? ChunkLevel.byStatus(ChunkStatus.FEATURES) : 33;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if MC_VER < MC_1_21_5
|
||||||
level.getChunkSource().distanceManager.addTicket(DH_SERVER_GEN_TICKET, pos, chunkLevel, pos);
|
level.getChunkSource().distanceManager.addTicket(DH_SERVER_GEN_TICKET, pos, chunkLevel, pos);
|
||||||
|
#else
|
||||||
|
level.getChunkSource().addTicketWithRadius(DH_SERVER_GEN_TICKET, pos, 0);
|
||||||
|
#endif
|
||||||
level.getChunkSource().distanceManager.runAllUpdates(level.getChunkSource().chunkMap); // probably not the most optimal to run updates here, but fast enough
|
level.getChunkSource().distanceManager.runAllUpdates(level.getChunkSource().chunkMap); // probably not the most optimal to run updates here, but fast enough
|
||||||
ChunkHolder holder = level.getChunkSource().chunkMap.getUpdatingChunkIfPresent(pos.toLong());
|
ChunkHolder holder = level.getChunkSource().chunkMap.getUpdatingChunkIfPresent(pos.toLong());
|
||||||
if (holder == null)
|
if (holder == null)
|
||||||
@@ -915,7 +955,11 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
|
|||||||
chunkLevel = chunkWasGeneratedUpToFeatures ? ChunkLevel.byStatus(ChunkStatus.FEATURES) : 33;
|
chunkLevel = chunkWasGeneratedUpToFeatures ? ChunkLevel.byStatus(ChunkStatus.FEATURES) : 33;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if MC_VER < MC_1_21_5
|
||||||
level.getChunkSource().distanceManager.removeTicket(DH_SERVER_GEN_TICKET, pos, chunkLevel, pos);
|
level.getChunkSource().distanceManager.removeTicket(DH_SERVER_GEN_TICKET, pos, chunkLevel, pos);
|
||||||
|
#else
|
||||||
|
level.getChunkSource().removeTicketWithRadius(DH_SERVER_GEN_TICKET, pos, 0);
|
||||||
|
#endif
|
||||||
|
|
||||||
// mitigate OOM issues in vanilla chunk system: see https://github.com/pop4959/Chunky/pull/383
|
// mitigate OOM issues in vanilla chunk system: see https://github.com/pop4959/Chunky/pull/383
|
||||||
level.getChunkSource().chunkMap.tick(() -> false);
|
level.getChunkSource().chunkMap.tick(() -> false);
|
||||||
@@ -1023,7 +1067,7 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
|
|||||||
|
|
||||||
// generate lighting using DH's lighting engine
|
// generate lighting using DH's lighting engine
|
||||||
|
|
||||||
int maxSkyLight = this.serverlevel.getServerLevelWrapper().hasSkyLight() ? 15 : 0;
|
int maxSkyLight = this.serverLevel.getServerLevelWrapper().hasSkyLight() ? 15 : 0;
|
||||||
|
|
||||||
// only light generated chunks,
|
// only light generated chunks,
|
||||||
// attempting to light un-generated chunks will cause lighting issues on bordering generated chunks
|
// attempting to light un-generated chunks will cause lighting issues on bordering generated chunks
|
||||||
@@ -1059,15 +1103,15 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
|
|||||||
DhLightingEngine.INSTANCE.bakeChunkBlockLighting(centerChunk, iChunkWrapperList, maxSkyLight);
|
DhLightingEngine.INSTANCE.bakeChunkBlockLighting(centerChunk, iChunkWrapperList, maxSkyLight);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.serverlevel.updateBeaconBeamsForChunk(centerChunk, iChunkWrapperList);
|
this.serverLevel.updateBeaconBeamsForChunk(centerChunk, iChunkWrapperList);
|
||||||
}
|
}
|
||||||
|
|
||||||
genEvent.refreshTimeout();
|
genEvent.refreshTimeout();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
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 - WORLD_GEN_CHUNK_BORDER_NEEDED_BY_GEN_STEP.get(step)); }
|
private static <T> ArrayGridList<T> GetCutoutFrom(ArrayGridList<T> total, EDhApiWorldGenerationStep step) { return GetCutoutFrom(total, 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); }
|
//private static <T> ArrayGridList<T> GetCutoutFrom(ArrayGridList<T> total, EDhApiWorldGenerationStep step) { return GetCutoutFrom(total, 0); }
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -1095,9 +1139,10 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
|
|||||||
{
|
{
|
||||||
regionStorage.close();
|
regionStorage.close();
|
||||||
}
|
}
|
||||||
|
catch (ClosedChannelException ignore) { /* world generator is being shut down */ }
|
||||||
catch (IOException e)
|
catch (IOException e)
|
||||||
{
|
{
|
||||||
EVENT_LOGGER.error("Failed to close region file storage cache!", e);
|
EVENT_LOGGER.error("Failed to close region file storage cache, error: ["+e.getMessage()+"].", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -32,11 +32,11 @@ import com.seibel.distanthorizons.core.util.objects.EventTimer;
|
|||||||
import com.seibel.distanthorizons.core.util.threading.ThreadPoolUtil;
|
import com.seibel.distanthorizons.core.util.threading.ThreadPoolUtil;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.chunk.IChunkWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.chunk.IChunkWrapper;
|
||||||
|
|
||||||
import org.apache.logging.log4j.Logger;
|
import com.seibel.distanthorizons.core.logging.DhLogger;
|
||||||
|
|
||||||
public final class GenerationEvent
|
public final class GenerationEvent
|
||||||
{
|
{
|
||||||
private static final Logger LOGGER = DhLoggerBuilder.getLogger(MethodHandles.lookup().lookupClass().getSimpleName());
|
private static final DhLogger LOGGER = new DhLoggerBuilder().build();;
|
||||||
private static int generationFutureDebugIDs = 0;
|
private static int generationFutureDebugIDs = 0;
|
||||||
|
|
||||||
public final int id;
|
public final int id;
|
||||||
|
|||||||
+434
-155
@@ -24,12 +24,14 @@ import com.mojang.serialization.Dynamic;
|
|||||||
import com.seibel.distanthorizons.common.wrappers.chunk.ChunkWrapper;
|
import com.seibel.distanthorizons.common.wrappers.chunk.ChunkWrapper;
|
||||||
import com.seibel.distanthorizons.common.wrappers.worldGeneration.BatchGenerationEnvironment;
|
import com.seibel.distanthorizons.common.wrappers.worldGeneration.BatchGenerationEnvironment;
|
||||||
|
|
||||||
import com.seibel.distanthorizons.core.logging.ConfigBasedLogger;
|
import com.seibel.distanthorizons.core.logging.DhLogger;
|
||||||
import com.seibel.distanthorizons.core.util.LodUtil;
|
import com.seibel.distanthorizons.core.util.LodUtil;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.chunk.ChunkLightStorage;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.chunk.ChunkLightStorage;
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import java.util.Optional;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
|
|
||||||
import it.unimi.dsi.fastutil.shorts.ShortList;
|
import it.unimi.dsi.fastutil.shorts.ShortList;
|
||||||
@@ -84,23 +86,30 @@ import net.minecraft.world.level.chunk.status.ChunkType;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
import net.minecraft.world.level.material.Fluid;
|
import net.minecraft.world.level.material.Fluid;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
|
||||||
public class ChunkLoader
|
public class ChunkFileReader
|
||||||
{
|
{
|
||||||
private static boolean zeroChunkPosErrorLogged = false;
|
private static final AtomicBoolean ZERO_CHUNK_POS_ERROR_LOGGED_REF = new AtomicBoolean(false);
|
||||||
|
|
||||||
#if MC_VER >= MC_1_19_2
|
private static final DhLogger LOGGER = BatchGenerationEnvironment.CHUNK_LOAD_LOGGER;
|
||||||
|
|
||||||
|
|
||||||
|
#if MC_VER >= MC_1_21_9
|
||||||
|
// BLOCK_STATE_CODEC can no longer be statically created since
|
||||||
|
// it needs a level reference
|
||||||
|
#elif MC_VER >= MC_1_19_2
|
||||||
private static final Codec<PalettedContainer<BlockState>> BLOCK_STATE_CODEC = PalettedContainer.codecRW(Block.BLOCK_STATE_REGISTRY, BlockState.CODEC, PalettedContainer.Strategy.SECTION_STATES, Blocks.AIR.defaultBlockState());
|
private static final Codec<PalettedContainer<BlockState>> BLOCK_STATE_CODEC = PalettedContainer.codecRW(Block.BLOCK_STATE_REGISTRY, BlockState.CODEC, PalettedContainer.Strategy.SECTION_STATES, Blocks.AIR.defaultBlockState());
|
||||||
#elif MC_VER >= MC_1_18_2
|
#elif MC_VER >= MC_1_18_2
|
||||||
private static final Codec<PalettedContainer<BlockState>> BLOCK_STATE_CODEC = PalettedContainer.codec(Block.BLOCK_STATE_REGISTRY, BlockState.CODEC, PalettedContainer.Strategy.SECTION_STATES, Blocks.AIR.defaultBlockState());
|
private static final Codec<PalettedContainer<BlockState>> BLOCK_STATE_CODEC = PalettedContainer.codec(Block.BLOCK_STATE_REGISTRY, BlockState.CODEC, PalettedContainer.Strategy.SECTION_STATES, Blocks.AIR.defaultBlockState());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
private static final String TAG_UPGRADE_DATA = "UpgradeData";
|
private static final String TAG_UPGRADE_DATA = "UpgradeData";
|
||||||
private static final String BLOCK_TICKS_TAG_18 = "block_ticks";
|
private static final String BLOCK_TICKS_TAG_18 = "block_ticks";
|
||||||
private static final String FLUID_TICKS_TAG_18 = "fluid_ticks";
|
private static final String FLUID_TICKS_TAG_18 = "fluid_ticks";
|
||||||
private static final String BLOCK_TICKS_TAG_PRE18 = "TileTicks";
|
private static final String BLOCK_TICKS_TAG_PRE18 = "TileTicks";
|
||||||
private static final String FLUID_TICKS_TAG_PRE18 = "LiquidTicks";
|
private static final String FLUID_TICKS_TAG_PRE18 = "LiquidTicks";
|
||||||
private static final ConfigBasedLogger LOGGER = BatchGenerationEnvironment.LOAD_LOGGER;
|
|
||||||
|
|
||||||
private static boolean lightingSectionErrorLogged = false;
|
private static boolean lightingSectionErrorLogged = false;
|
||||||
|
|
||||||
@@ -120,19 +129,16 @@ public class ChunkLoader
|
|||||||
CompoundTag tagLevel = chunkData;
|
CompoundTag tagLevel = chunkData;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ChunkPos actualPos = new ChunkPos(tagLevel.getInt("xPos"), tagLevel.getInt("zPos"));
|
int chunkX = tagGetInt(tagLevel,"xPos");
|
||||||
|
int chunkZ = tagGetInt(tagLevel, "zPos");
|
||||||
|
ChunkPos actualPos = new ChunkPos(chunkX, chunkZ);
|
||||||
|
|
||||||
if (!Objects.equals(chunkPos, actualPos))
|
if (!Objects.equals(chunkPos, actualPos))
|
||||||
{
|
{
|
||||||
#if MC_VER >= MC_1_18_2
|
if (chunkX == 0 && chunkZ == 0)
|
||||||
if (actualPos.equals(ChunkPos.ZERO))
|
|
||||||
#else
|
|
||||||
if (actualPos.equals(ChunkPos.INVALID_CHUNK_POS))
|
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
if (!zeroChunkPosErrorLogged)
|
if (!ZERO_CHUNK_POS_ERROR_LOGGED_REF.getAndSet(true))
|
||||||
{
|
{
|
||||||
zeroChunkPosErrorLogged = true;
|
|
||||||
|
|
||||||
// explicit chunkPos toString is necessary otherwise the JDK 17 compiler breaks
|
// explicit chunkPos toString is necessary otherwise the JDK 17 compiler breaks
|
||||||
LOGGER.warn("Chunk file at ["+chunkPos.toString()+"] doesn't have a chunk pos. \n" +
|
LOGGER.warn("Chunk file at ["+chunkPos.toString()+"] doesn't have a chunk pos. \n" +
|
||||||
"This might happen if the world was created using an external program. \n" +
|
"This might happen if the world was created using an external program. \n" +
|
||||||
@@ -161,7 +167,7 @@ public class ChunkLoader
|
|||||||
#if MC_VER < MC_1_18_2
|
#if MC_VER < MC_1_18_2
|
||||||
if (chunkType != ChunkStatus.ChunkType.LEVELCHUNK)
|
if (chunkType != ChunkStatus.ChunkType.LEVELCHUNK)
|
||||||
return null;
|
return null;
|
||||||
#else
|
#elif MC_VER < MC_1_21_6
|
||||||
|
|
||||||
BlendingData blendingData = readBlendingData(tagLevel);
|
BlendingData blendingData = readBlendingData(tagLevel);
|
||||||
#if MC_VER < MC_1_19_2
|
#if MC_VER < MC_1_19_2
|
||||||
@@ -171,17 +177,42 @@ public class ChunkLoader
|
|||||||
if (chunkType == #if MC_VER < MC_1_20_6 ChunkStatus.ChunkType.PROTOCHUNK #else ChunkType.PROTOCHUNK #endif && blendingData == null)
|
if (chunkType == #if MC_VER < MC_1_20_6 ChunkStatus.ChunkType.PROTOCHUNK #else ChunkType.PROTOCHUNK #endif && blendingData == null)
|
||||||
return null;
|
return null;
|
||||||
#endif
|
#endif
|
||||||
|
#else
|
||||||
|
|
||||||
|
// ignore blending data, there appears to be an issue with parsing it in 1.21.6
|
||||||
|
BlendingData blendingData = null;
|
||||||
|
|
||||||
|
if (chunkType == ChunkType.PROTOCHUNK)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
long inhabitedTime = tagLevel.getLong("InhabitedTime");
|
long inhabitedTime = tagGetLong(tagLevel, "InhabitedTime");
|
||||||
|
|
||||||
//================== Read params for making the LevelChunk ==================
|
//================== Read params for making the LevelChunk ==================
|
||||||
UpgradeData upgradeData = tagLevel.contains(TAG_UPGRADE_DATA, 10)
|
|
||||||
? new UpgradeData(tagLevel.getCompound(TAG_UPGRADE_DATA)#if MC_VER >= MC_1_17_1 , level #endif )
|
|
||||||
: UpgradeData.EMPTY;
|
|
||||||
|
|
||||||
boolean isLightOn = tagLevel.getBoolean("isLightOn");
|
UpgradeData upgradeData = UpgradeData.EMPTY;
|
||||||
|
// commented out 2025-06-04 as a test to see if the upgrade data
|
||||||
|
// is actually necessary for DH or if it can be ignored
|
||||||
|
// (if it can't be ignored we'll need to handle null responses from tagGetCompoundTag())
|
||||||
|
//
|
||||||
|
//#if MC_VER < MC_1_17_1
|
||||||
|
//upgradeData = tagLevel.contains(TAG_UPGRADE_DATA, 10)
|
||||||
|
// ? new UpgradeData(tagGetCompoundTag(tagLevel, TAG_UPGRADE_DATA))
|
||||||
|
// : UpgradeData.EMPTY;
|
||||||
|
//#elif MC_VER < MC_1_21_5
|
||||||
|
//upgradeData = tagLevel.contains(TAG_UPGRADE_DATA, 10)
|
||||||
|
// ? new UpgradeData(tagGetCompoundTag(tagLevel, TAG_UPGRADE_DATA), level)
|
||||||
|
// : UpgradeData.EMPTY;
|
||||||
|
//#else
|
||||||
|
//upgradeData = tagLevel.contains(TAG_UPGRADE_DATA)
|
||||||
|
// ? new UpgradeData(tagGetCompoundTag(tagLevel, TAG_UPGRADE_DATA), level)
|
||||||
|
// : UpgradeData.EMPTY;
|
||||||
|
//#endif
|
||||||
|
|
||||||
|
|
||||||
|
boolean isLightOn = tagGetBoolean(tagLevel, "isLightOn");
|
||||||
#if MC_VER < MC_1_18_2
|
#if MC_VER < MC_1_18_2
|
||||||
ChunkBiomeContainer chunkBiomeContainer = new ChunkBiomeContainer(
|
ChunkBiomeContainer chunkBiomeContainer = new ChunkBiomeContainer(
|
||||||
level.getLevel().registryAccess().registryOrThrow(Registry.BIOME_REGISTRY)#if MC_VER >= MC_1_17_1 , level #endif ,
|
level.getLevel().registryAccess().registryOrThrow(Registry.BIOME_REGISTRY)#if MC_VER >= MC_1_17_1 , level #endif ,
|
||||||
@@ -198,17 +229,21 @@ public class ChunkLoader
|
|||||||
: new ProtoTickList<Fluid>(fluid -> (fluid == null || fluid == Fluids.EMPTY), chunkPos,
|
: new ProtoTickList<Fluid>(fluid -> (fluid == null || fluid == Fluids.EMPTY), chunkPos,
|
||||||
tagLevel.getList("LiquidsToBeTicked", 9)#if MC_VER >= MC_1_17_1 , level #endif );
|
tagLevel.getList("LiquidsToBeTicked", 9)#if MC_VER >= MC_1_17_1 , level #endif );
|
||||||
#else
|
#else
|
||||||
#if MC_VER < MC_1_19_4
|
#if MC_VER < MC_1_19_4
|
||||||
LevelChunkTicks<Block> blockTicks = LevelChunkTicks.load(tagLevel.getList(BLOCK_TICKS_TAG_18, 10),
|
LevelChunkTicks<Block> blockTicks = LevelChunkTicks.load(tagLevel.getList(BLOCK_TICKS_TAG_18, 10),
|
||||||
string -> Registry.BLOCK.getOptional(ResourceLocation.tryParse(string)), chunkPos);
|
string -> Registry.BLOCK.getOptional(ResourceLocation.tryParse(string)), chunkPos);
|
||||||
LevelChunkTicks<Fluid> fluidTicks = LevelChunkTicks.load(tagLevel.getList(FLUID_TICKS_TAG_18, 10),
|
LevelChunkTicks<Fluid> fluidTicks = LevelChunkTicks.load(tagLevel.getList(FLUID_TICKS_TAG_18, 10),
|
||||||
string -> Registry.FLUID.getOptional(ResourceLocation.tryParse(string)), chunkPos);
|
string -> Registry.FLUID.getOptional(ResourceLocation.tryParse(string)), chunkPos);
|
||||||
#else
|
#elif MC_VER < MC_1_21_4
|
||||||
LevelChunkTicks<Block> blockTicks = LevelChunkTicks.load(tagLevel.getList(BLOCK_TICKS_TAG_18, 10),
|
LevelChunkTicks<Block> blockTicks = LevelChunkTicks.load(tagLevel.getList(BLOCK_TICKS_TAG_18, 10),
|
||||||
(string -> BuiltInRegistries.BLOCK.getOptional(ResourceLocation.tryParse(string))), chunkPos);
|
(string -> BuiltInRegistries.BLOCK.getOptional(ResourceLocation.tryParse(string))), chunkPos);
|
||||||
LevelChunkTicks<Fluid> fluidTicks = LevelChunkTicks.load(tagLevel.getList(FLUID_TICKS_TAG_18, 10),
|
LevelChunkTicks<Fluid> fluidTicks = LevelChunkTicks.load(tagLevel.getList(FLUID_TICKS_TAG_18, 10),
|
||||||
string -> BuiltInRegistries.FLUID.getOptional(ResourceLocation.tryParse(string)), chunkPos);
|
string -> BuiltInRegistries.FLUID.getOptional(ResourceLocation.tryParse(string)), chunkPos);
|
||||||
#endif
|
#else
|
||||||
|
// do we need the ticks for what we're doing?
|
||||||
|
LevelChunkTicks<Block> blockTicks = new LevelChunkTicks<>();
|
||||||
|
LevelChunkTicks<Fluid> fluidTicks = new LevelChunkTicks<>();
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
LevelChunkSection[] levelChunkSections = readSections(level, chunkPos, tagLevel);
|
LevelChunkSection[] levelChunkSections = readSections(level, chunkPos, tagLevel);
|
||||||
@@ -218,18 +253,25 @@ public class ChunkLoader
|
|||||||
LevelChunk chunk = new LevelChunk((Level) level.getLevel(), chunkPos, chunkBiomeContainer, upgradeData, blockTicks,
|
LevelChunk chunk = new LevelChunk((Level) level.getLevel(), chunkPos, chunkBiomeContainer, upgradeData, blockTicks,
|
||||||
fluidTicks, inhabitedTime, levelChunkSections, null);
|
fluidTicks, inhabitedTime, levelChunkSections, null);
|
||||||
#else
|
#else
|
||||||
|
|
||||||
LevelChunk chunk = new LevelChunk((Level) level, chunkPos, upgradeData, blockTicks,
|
LevelChunk chunk = new LevelChunk((Level) level, chunkPos, upgradeData, blockTicks,
|
||||||
fluidTicks, inhabitedTime, levelChunkSections, null, blendingData);
|
fluidTicks, inhabitedTime, levelChunkSections, null, blendingData);
|
||||||
#endif
|
#endif
|
||||||
// Set some states after object creation
|
// Set some states after object creation
|
||||||
chunk.setLightCorrect(isLightOn);
|
chunk.setLightCorrect(isLightOn);
|
||||||
readHeightmaps(chunk, chunkData);
|
readHeightmaps(chunk, chunkData);
|
||||||
readPostPocessings(chunk, chunkData);
|
//readPostPocessings(chunk, chunkData);
|
||||||
return chunk;
|
return chunk;
|
||||||
}
|
}
|
||||||
private static LevelChunkSection[] readSections(LevelAccessor level, ChunkPos chunkPos, CompoundTag chunkData)
|
private static LevelChunkSection[] readSections(LevelAccessor level, ChunkPos chunkPos, CompoundTag chunkData)
|
||||||
{
|
{
|
||||||
|
#if MC_VER < MC_1_21_9
|
||||||
|
// BLOCK_STATE_CODEC is created statically
|
||||||
|
// TODO clean up this code separation
|
||||||
|
#else
|
||||||
|
final Codec<PalettedContainer<BlockState>> BLOCK_STATE_CODEC = PalettedContainerFactory.create(level.registryAccess()).blockStatesContainerCodec();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#if MC_VER >= MC_1_18_2
|
#if MC_VER >= MC_1_18_2
|
||||||
#if MC_VER < MC_1_19_4
|
#if MC_VER < MC_1_19_4
|
||||||
Registry<Biome> biomes = level.registryAccess().registryOrThrow(Registry.BIOME_REGISTRY);
|
Registry<Biome> biomes = level.registryAccess().registryOrThrow(Registry.BIOME_REGISTRY);
|
||||||
@@ -247,95 +289,142 @@ public class ChunkLoader
|
|||||||
#elif MC_VER < MC_1_21_3
|
#elif MC_VER < MC_1_21_3
|
||||||
Codec<PalettedContainer<Holder<Biome>>> biomeCodec = PalettedContainer.codecRW(
|
Codec<PalettedContainer<Holder<Biome>>> biomeCodec = PalettedContainer.codecRW(
|
||||||
biomes.asHolderIdMap(), biomes.holderByNameCodec(), PalettedContainer.Strategy.SECTION_BIOMES, biomes.getHolderOrThrow(Biomes.PLAINS));
|
biomes.asHolderIdMap(), biomes.holderByNameCodec(), PalettedContainer.Strategy.SECTION_BIOMES, biomes.getHolderOrThrow(Biomes.PLAINS));
|
||||||
#else
|
#elif MC_VER < MC_1_21_9
|
||||||
Codec<PalettedContainer<Holder<Biome>>> biomeCodec = PalettedContainer.codecRW(
|
Codec<PalettedContainer<Holder<Biome>>> biomeCodec = PalettedContainer.codecRW(
|
||||||
biomes.asHolderIdMap(), biomes.holderByNameCodec(), PalettedContainer.Strategy.SECTION_BIOMES, biomes.getOrThrow(Biomes.PLAINS));
|
biomes.asHolderIdMap(), biomes.holderByNameCodec(), PalettedContainer.Strategy.SECTION_BIOMES, biomes.getOrThrow(Biomes.PLAINS));
|
||||||
|
#else
|
||||||
|
Codec<PalettedContainer<Holder<Biome>>> biomeCodec = PalettedContainer.codecRW(
|
||||||
|
biomes.holderByNameCodec(), PalettedContainerFactory.create(level.registryAccess()).biomeStrategy(), biomes.getOrThrow(Biomes.PLAINS));
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int sectionYIndex = #if MC_VER < MC_1_17_1 16; #else level.getSectionsCount(); #endif
|
int sectionYIndex = #if MC_VER < MC_1_17_1 16; #else level.getSectionsCount(); #endif
|
||||||
LevelChunkSection[] chunkSections = new LevelChunkSection[sectionYIndex];
|
LevelChunkSection[] chunkSections = new LevelChunkSection[sectionYIndex];
|
||||||
|
|
||||||
boolean isLightOn = chunkData.getBoolean("isLightOn");
|
ListTag tagSections = tagGetListTag(chunkData, "Sections", 10);
|
||||||
boolean hasSkyLight = level.dimensionType().hasSkyLight();
|
if (tagSections == null || tagSections.isEmpty())
|
||||||
ListTag tagSections = chunkData.getList("Sections", 10);
|
|
||||||
if (tagSections.isEmpty()) tagSections = chunkData.getList("sections", 10);
|
|
||||||
|
|
||||||
for (int j = 0; j < tagSections.size(); ++j)
|
|
||||||
{
|
{
|
||||||
CompoundTag tagSection = tagSections.getCompound(j);
|
tagSections = tagGetListTag(chunkData, "sections", 10);
|
||||||
int sectionYPos = tagSection.getByte("Y");
|
}
|
||||||
|
|
||||||
#if MC_VER < MC_1_18_2
|
|
||||||
if (tagSection.contains("Palette", 9) && tagSection.contains("BlockStates", 12))
|
if (tagSections != null)
|
||||||
|
{
|
||||||
|
for (int j = 0; j < tagSections.size(); ++j)
|
||||||
{
|
{
|
||||||
LevelChunkSection levelChunkSection = new LevelChunkSection(sectionYPos << 4);
|
CompoundTag tagSection = tagGetCompoundTag(tagSections, j);
|
||||||
levelChunkSection.getStates().read(tagSection.getList("Palette", 10),
|
if (tagSection == null)
|
||||||
tagSection.getLongArray("BlockStates"));
|
{
|
||||||
levelChunkSection.recalcBlockCounts();
|
continue;
|
||||||
if (!levelChunkSection.isEmpty())
|
}
|
||||||
chunkSections[#if MC_VER < MC_1_17_1 sectionYPos #else level.getSectionIndexFromSectionY(sectionYPos) #endif ]
|
|
||||||
= levelChunkSection;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
int sectionId = level.getSectionIndexFromSectionY(sectionYPos);
|
|
||||||
if (sectionId >= 0 && sectionId < chunkSections.length)
|
|
||||||
{
|
|
||||||
PalettedContainer<BlockState> blockStateContainer;
|
|
||||||
#if MC_VER < MC_1_18_2
|
|
||||||
PalettedContainer<Biome> biomeContainer;
|
|
||||||
#else
|
|
||||||
PalettedContainer<Holder<Biome>> biomeContainer;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
blockStateContainer = tagSection.contains("block_states", 10)
|
final int sectionYPos = tagGetByte(tagSection, "Y");
|
||||||
? BLOCK_STATE_CODEC.parse(NbtOps.INSTANCE, tagSection.getCompound("block_states"))
|
|
||||||
|
#if MC_VER < MC_1_18_2
|
||||||
|
if (tagSection.contains("Palette", 9) && tagSection.contains("BlockStates", 12))
|
||||||
|
{
|
||||||
|
LevelChunkSection levelChunkSection = new LevelChunkSection(sectionYPos << 4);
|
||||||
|
levelChunkSection.getStates().read(tagSection.getList("Palette", 10),
|
||||||
|
tagSection.getLongArray("BlockStates"));
|
||||||
|
levelChunkSection.recalcBlockCounts();
|
||||||
|
if (!levelChunkSection.isEmpty())
|
||||||
|
chunkSections[#if MC_VER < MC_1_17_1 sectionYPos #else level.getSectionIndexFromSectionY(sectionYPos) #endif ]
|
||||||
|
= levelChunkSection;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
int sectionId = level.getSectionIndexFromSectionY(sectionYPos);
|
||||||
|
if (sectionId >= 0 && sectionId < chunkSections.length)
|
||||||
|
{
|
||||||
|
PalettedContainer<BlockState> blockStateContainer;
|
||||||
|
#if MC_VER < MC_1_18_2
|
||||||
|
PalettedContainer<Biome> biomeContainer;
|
||||||
|
#else
|
||||||
|
PalettedContainer<Holder<Biome>> biomeContainer;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
boolean containsBlockStates;
|
||||||
|
#if MC_VER < MC_1_21_5
|
||||||
|
containsBlockStates = tagSection.contains("block_states", 10);
|
||||||
|
#else
|
||||||
|
containsBlockStates = tagSection.contains("block_states");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (containsBlockStates)
|
||||||
|
{
|
||||||
|
#if MC_VER < MC_1_20_6
|
||||||
|
blockStateContainer = BLOCK_STATE_CODEC.parse(NbtOps.INSTANCE, tagGetCompoundTag(tagSection, "block_states"))
|
||||||
.promotePartial(string -> logBlockDeserializationWarning(chunkPos, sectionYPos, string))
|
.promotePartial(string -> logBlockDeserializationWarning(chunkPos, sectionYPos, string))
|
||||||
#if MC_VER < MC_1_20_6
|
.getOrThrow(false, (message) -> logParsingWarningOnce(message));
|
||||||
.getOrThrow(false, (message) -> logWarningOnce(message))
|
|
||||||
#else
|
#else
|
||||||
.getOrThrow((message) -> logErrorAndReturnException(message))
|
blockStateContainer = BLOCK_STATE_CODEC.parse(NbtOps.INSTANCE, tagGetCompoundTag(tagSection, "block_states"))
|
||||||
|
.promotePartial(string -> logBlockDeserializationWarning(chunkPos, sectionYPos, string))
|
||||||
|
.getOrThrow((message) -> logErrorAndReturnException(message));
|
||||||
#endif
|
#endif
|
||||||
: new PalettedContainer<BlockState>(Block.BLOCK_STATE_REGISTRY, Blocks.AIR.defaultBlockState(), PalettedContainer.Strategy.SECTION_STATES);
|
}
|
||||||
|
else
|
||||||
#if MC_VER < MC_1_18_2
|
{
|
||||||
biomeContainer = tagSection.contains("biomes", 10)
|
#if MC_VER < MC_1_21_9
|
||||||
? biomeCodec.parse(NbtOps.INSTANCE, tagSection.getCompound("biomes")).promotePartial(string -> logErrors(chunkPos, sectionYPos, string)).getOrThrow(false, (message) -> logWarningOnce(message))
|
blockStateContainer = new PalettedContainer<BlockState>(Block.BLOCK_STATE_REGISTRY, Blocks.AIR.defaultBlockState(), PalettedContainer.Strategy.SECTION_STATES);
|
||||||
: new PalettedContainer<Biome>(biomes, biomes.getOrThrow(Biomes.PLAINS), PalettedContainer.Strategy.SECTION_BIOMES);
|
#else
|
||||||
#else
|
blockStateContainer = PalettedContainerFactory.create(level.registryAccess()).createForBlockStates();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (tagSection.contains("biomes", 10))
|
#if MC_VER < MC_1_18_2
|
||||||
{
|
biomeContainer = tagSection.contains("biomes", 10)
|
||||||
biomeContainer =
|
? biomeCodec.parse(NbtOps.INSTANCE, tagSection.getCompound("biomes")).promotePartial(string -> logErrors(chunkPos, sectionYPos, string)).getOrThrow(false, (message) -> logWarningOnce(message))
|
||||||
biomeCodec.parse(NbtOps.INSTANCE, tagSection.getCompound("biomes"))
|
: new PalettedContainer<Biome>(biomes, biomes.getOrThrow(Biomes.PLAINS), PalettedContainer.Strategy.SECTION_BIOMES);
|
||||||
|
#else
|
||||||
|
|
||||||
|
|
||||||
|
boolean containsBiomes;
|
||||||
|
#if MC_VER < MC_1_21_5
|
||||||
|
containsBiomes = tagSection.contains("biomes", 10);
|
||||||
|
#else
|
||||||
|
containsBiomes = tagSection.contains("biomes");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (containsBiomes)
|
||||||
|
{
|
||||||
|
#if MC_VER < MC_1_20_6
|
||||||
|
biomeContainer = biomeCodec.parse(NbtOps.INSTANCE, tagGetCompoundTag(tagSection, "biomes"))
|
||||||
|
.promotePartial(string -> logBiomeDeserializationWarning(chunkPos, sectionYIndex, (String) string))
|
||||||
|
.getOrThrow(false, (message) -> logParsingWarningOnce(message));
|
||||||
|
#else
|
||||||
|
biomeContainer = biomeCodec.parse(NbtOps.INSTANCE, tagGetCompoundTag(tagSection, "biomes"))
|
||||||
.promotePartial(string -> logBiomeDeserializationWarning(chunkPos, sectionYIndex, (String) string))
|
.promotePartial(string -> logBiomeDeserializationWarning(chunkPos, sectionYIndex, (String) string))
|
||||||
#if MC_VER < MC_1_20_6
|
.getOrThrow((message) -> logErrorAndReturnException(message));
|
||||||
.getOrThrow(false, (message) -> logWarningOnce(message));
|
|
||||||
#else
|
|
||||||
.getOrThrow((message) -> logErrorAndReturnException(message));
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
biomeContainer = new PalettedContainer<Holder<Biome>>(biomes.asHolderIdMap(),
|
#if MC_VER < MC_1_21_3
|
||||||
#if MC_VER < MC_1_21_3
|
biomeContainer = new PalettedContainer<Holder<Biome>>(
|
||||||
biomes.getHolderOrThrow(Biomes.PLAINS),
|
biomes.asHolderIdMap(),
|
||||||
#else
|
biomes.getHolderOrThrow(Biomes.PLAINS), PalettedContainer.Strategy.SECTION_BIOMES);
|
||||||
biomes.getOrThrow(Biomes.PLAINS),
|
#elif MC_VER < MC_1_21_9
|
||||||
#endif
|
biomeContainer = new PalettedContainer<Holder<Biome>>(biomes.asHolderIdMap(),
|
||||||
PalettedContainer.Strategy.SECTION_BIOMES);
|
biomes.getOrThrow(Biomes.PLAINS),
|
||||||
}
|
PalettedContainer.Strategy.SECTION_BIOMES);
|
||||||
|
#else
|
||||||
|
biomeContainer = PalettedContainerFactory.create(level.registryAccess()).createForBiomes();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if MC_VER < MC_1_20_1
|
||||||
|
chunkSections[sectionId] = new LevelChunkSection(sectionYPos, blockStateContainer, biomeContainer);
|
||||||
|
#else
|
||||||
|
chunkSections[sectionId] = new LevelChunkSection(blockStateContainer, biomeContainer);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if MC_VER < MC_1_20_1
|
}
|
||||||
chunkSections[sectionId] = new LevelChunkSection(sectionYPos, blockStateContainer, biomeContainer);
|
|
||||||
#else
|
|
||||||
chunkSections[sectionId] = new LevelChunkSection(blockStateContainer, biomeContainer);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}
|
}
|
||||||
return chunkSections;
|
return chunkSections;
|
||||||
}
|
}
|
||||||
@@ -345,57 +434,108 @@ public class ChunkLoader
|
|||||||
#else ChunkType #endif
|
#else ChunkType #endif
|
||||||
readChunkType(CompoundTag tagLevel)
|
readChunkType(CompoundTag tagLevel)
|
||||||
{
|
{
|
||||||
ChunkStatus chunkStatus = ChunkStatus.byName(tagLevel.getString("Status"));
|
String statusString = tagGetString(tagLevel,"Status");
|
||||||
if (chunkStatus != null)
|
if (statusString != null)
|
||||||
{
|
{
|
||||||
return chunkStatus.getChunkType();
|
ChunkStatus chunkStatus = ChunkStatus.byName(statusString);
|
||||||
|
if (chunkStatus != null)
|
||||||
|
{
|
||||||
|
return chunkStatus.getChunkType();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
#if MC_VER <= MC_1_20_4
|
||||||
#if MC_VER <= MC_1_20_4 ChunkStatus.ChunkType.PROTOCHUNK;
|
return ChunkStatus.ChunkType.PROTOCHUNK;
|
||||||
#else ChunkType.PROTOCHUNK; #endif
|
#else
|
||||||
|
return ChunkType.PROTOCHUNK;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
private static void readHeightmaps(LevelChunk chunk, CompoundTag chunkData)
|
private static void readHeightmaps(LevelChunk chunk, CompoundTag chunkData)
|
||||||
{
|
{
|
||||||
CompoundTag tagHeightmaps = chunkData.getCompound("Heightmaps");
|
CompoundTag tagHeightmaps = tagGetCompoundTag(chunkData, "Heightmaps");
|
||||||
for (Heightmap.Types type : ChunkStatus.FULL.heightmapsAfter())
|
if (tagHeightmaps != null)
|
||||||
{
|
{
|
||||||
String heightmap = type.getSerializationKey();
|
for (Heightmap.Types type : ChunkStatus.FULL.heightmapsAfter())
|
||||||
if (tagHeightmaps.contains(heightmap, 12))
|
|
||||||
chunk.setHeightmap(type, tagHeightmaps.getLongArray(heightmap));
|
|
||||||
}
|
|
||||||
Heightmap.primeHeightmaps(chunk, ChunkStatus.FULL.heightmapsAfter());
|
|
||||||
}
|
|
||||||
private static void readPostPocessings(LevelChunk chunk, CompoundTag chunkData)
|
|
||||||
{
|
|
||||||
ListTag tagPostProcessings = chunkData.getList("PostProcessing", 9);
|
|
||||||
for (int i = 0; i < tagPostProcessings.size(); ++i)
|
|
||||||
{
|
|
||||||
ListTag listTag3 = tagPostProcessings.getList(i);
|
|
||||||
for (int j = 0; j < listTag3.size(); ++j)
|
|
||||||
{
|
{
|
||||||
#if MC_VER < MC_1_21_3
|
String heightmap = type.getSerializationKey();
|
||||||
chunk.addPackedPostProcess(listTag3.getShort(j), i);
|
#if MC_VER < MC_1_21_5
|
||||||
|
if (tagHeightmaps.contains(heightmap, 12))
|
||||||
|
{
|
||||||
|
chunk.setHeightmap(type, tagHeightmaps.getLongArray(heightmap));
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
chunk.addPackedPostProcess(ShortList.of(listTag3.getShort(j)), i);
|
if (tagHeightmaps.contains(heightmap))
|
||||||
|
{
|
||||||
|
Optional<long[]> optionalHeightmap = tagHeightmaps.getLongArray(heightmap);
|
||||||
|
if (optionalHeightmap.isPresent())
|
||||||
|
{
|
||||||
|
chunk.setHeightmap(type, optionalHeightmap.get());
|
||||||
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Heightmap.primeHeightmaps(chunk, ChunkStatus.FULL.heightmapsAfter());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// commented out as a test as of 2025-06-04 to see if this is actually necessary for DH
|
||||||
|
// DH probably doesn't need any chunk post-processing data
|
||||||
|
//private static void readPostPocessings(LevelChunk chunk, CompoundTag chunkData)
|
||||||
|
//{
|
||||||
|
// ListTag tagPostProcessings = tagGetListTag(chunkData,"PostProcessing", 9);
|
||||||
|
// if (tagPostProcessings != null)
|
||||||
|
// {
|
||||||
|
// for (int i = 0; i < tagPostProcessings.size(); ++i)
|
||||||
|
// {
|
||||||
|
// ListTag listTag3 = tagGetListTag(tagPostProcessings, i);
|
||||||
|
// for (int j = 0; j < listTag3.size(); ++j)
|
||||||
|
// {
|
||||||
|
// #if MC_VER < MC_1_21_3
|
||||||
|
// chunk.addPackedPostProcess(listTag3.getShort(j), i);
|
||||||
|
// #else
|
||||||
|
// chunk.addPackedPostProcess(ShortList.of(tagGetShort(listTag3, j)), i);
|
||||||
|
// #endif
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//}
|
||||||
#if MC_VER >= MC_1_18_2
|
#if MC_VER >= MC_1_18_2
|
||||||
private static BlendingData readBlendingData(CompoundTag chunkData)
|
private static BlendingData readBlendingData(CompoundTag chunkData)
|
||||||
{
|
{
|
||||||
BlendingData blendingData = null;
|
BlendingData blendingData = null;
|
||||||
if (chunkData.contains("blending_data", 10))
|
|
||||||
|
|
||||||
|
boolean containsBlendingData;
|
||||||
|
#if MC_VER < MC_1_21_5
|
||||||
|
containsBlendingData = chunkData.contains("blending_data", 10);
|
||||||
|
#else
|
||||||
|
containsBlendingData = chunkData.contains("blending_data");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (containsBlendingData)
|
||||||
{
|
{
|
||||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||||
Dynamic<CompoundTag> blendingDataTag = new Dynamic(NbtOps.INSTANCE, chunkData.getCompound("blending_data"));
|
Dynamic<CompoundTag> blendingDataTag = new Dynamic(NbtOps.INSTANCE, chunkData.getCompound("blending_data"));
|
||||||
|
|
||||||
#if MC_VER < MC_1_21_3
|
try
|
||||||
blendingData = BlendingData.CODEC.parse(blendingDataTag).resultOrPartial((message) -> logWarningOnce(message)).orElse(null);
|
{
|
||||||
#else
|
#if MC_VER < MC_1_21_3
|
||||||
blendingData = BlendingData.unpack(BlendingData.Packed.CODEC.parse(blendingDataTag).resultOrPartial((message) -> logWarningOnce(message)).orElse(null));
|
blendingData = BlendingData.CODEC.parse(blendingDataTag).resultOrPartial((message) -> logParsingWarningOnce(message)).orElse(null);
|
||||||
#endif
|
#else
|
||||||
|
// blending data appears to have changed as of 1.21.6 causing a class cast exception here due to it being wrapped in a Java.Optional
|
||||||
|
blendingData = BlendingData.unpack(BlendingData.Packed.CODEC.parse(blendingDataTag).resultOrPartial((message) -> logParsingWarningOnce(message)).orElse(null));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
String message = e.getMessage();
|
||||||
|
if (message == null || message.trim().isEmpty())
|
||||||
|
{
|
||||||
|
message = "Failed to parse blending data";
|
||||||
|
}
|
||||||
|
|
||||||
|
logParsingWarningOnce(message, e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return blendingData;
|
return blendingData;
|
||||||
}
|
}
|
||||||
@@ -472,33 +612,37 @@ public class ChunkLoader
|
|||||||
|
|
||||||
|
|
||||||
// if null all lights = 0
|
// if null all lights = 0
|
||||||
byte[] blockLightNibbleArray = chunkSectionCompoundTag.getByteArray("BlockLight");
|
byte[] blockLightNibbleArray = tagGetByteArray(chunkSectionCompoundTag, "BlockLight");
|
||||||
byte[] skyLightNibbleArray = chunkSectionCompoundTag.getByteArray("SkyLight");
|
byte[] skyLightNibbleArray = tagGetByteArray(chunkSectionCompoundTag, "SkyLight");
|
||||||
|
|
||||||
// if any sky light was found then all lights above will be max brightness
|
if (blockLightNibbleArray != null
|
||||||
if (skyLightNibbleArray.length != 0)
|
&& skyLightNibbleArray != null)
|
||||||
{
|
{
|
||||||
foundSkyLight = true;
|
// if any sky light was found then all lights above will be max brightness
|
||||||
}
|
if (skyLightNibbleArray.length != 0)
|
||||||
|
|
||||||
for (int relX = 0; relX < LodUtil.CHUNK_WIDTH; relX++)
|
|
||||||
{
|
|
||||||
for (int relZ = 0; relZ < LodUtil.CHUNK_WIDTH; relZ++)
|
|
||||||
{
|
{
|
||||||
// chunk sections are also 16 blocks tall
|
foundSkyLight = true;
|
||||||
for (int relY = 0; relY < LodUtil.CHUNK_WIDTH; relY++)
|
}
|
||||||
|
|
||||||
|
for (int relX = 0; relX < LodUtil.CHUNK_WIDTH; relX++)
|
||||||
|
{
|
||||||
|
for (int relZ = 0; relZ < LodUtil.CHUNK_WIDTH; relZ++)
|
||||||
{
|
{
|
||||||
int blockPosIndex = relY*16*16 + relZ*16 + relX;
|
// chunk sections are also 16 blocks tall
|
||||||
byte blockLight = (blockLightNibbleArray.length == 0) ? 0 : getNibbleAtIndex(blockLightNibbleArray, blockPosIndex);
|
for (int relY = 0; relY < LodUtil.CHUNK_WIDTH; relY++)
|
||||||
byte skyLight = (skyLightNibbleArray.length == 0) ? 0 : getNibbleAtIndex(skyLightNibbleArray, blockPosIndex);
|
|
||||||
if (skyLightNibbleArray.length == 0 && foundSkyLight)
|
|
||||||
{
|
{
|
||||||
skyLight = LodUtil.MAX_MC_LIGHT;
|
int blockPosIndex = relY*16*16 + relZ*16 + relX;
|
||||||
|
byte blockLight = (blockLightNibbleArray.length == 0) ? 0 : getNibbleAtIndex(blockLightNibbleArray, blockPosIndex);
|
||||||
|
byte skyLight = (skyLightNibbleArray.length == 0) ? 0 : getNibbleAtIndex(skyLightNibbleArray, blockPosIndex);
|
||||||
|
if (skyLightNibbleArray.length == 0 && foundSkyLight)
|
||||||
|
{
|
||||||
|
skyLight = LodUtil.MAX_MC_LIGHT;
|
||||||
|
}
|
||||||
|
|
||||||
|
int y = relY + (sectionIndex * LodUtil.CHUNK_WIDTH) + ChunkWrapper.getInclusiveMinBuildHeight(chunk);
|
||||||
|
blockLightStorage.set(relX, y, relZ, blockLight);
|
||||||
|
skyLightStorage.set(relX, y, relZ, skyLight);
|
||||||
}
|
}
|
||||||
|
|
||||||
int y = relY + (sectionIndex * LodUtil.CHUNK_WIDTH) + ChunkWrapper.getInclusiveMinBuildHeight(chunk);
|
|
||||||
blockLightStorage.set(relX, y, relZ, blockLight);
|
|
||||||
skyLightStorage.set(relX, y, relZ, skyLight);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -547,9 +691,14 @@ public class ChunkLoader
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void logWarningOnce(String message) { logWarningOnce(message, null); }
|
private static void logParsingWarningOnce(String message) { logParsingWarningOnce(message, null); }
|
||||||
private static void logWarningOnce(String message, Exception e)
|
private static void logParsingWarningOnce(String message, Exception e)
|
||||||
{
|
{
|
||||||
|
if (message == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
LOGGED_ERROR_MESSAGE_MAP.computeIfAbsent(message, (newMessage) ->
|
LOGGED_ERROR_MESSAGE_MAP.computeIfAbsent(message, (newMessage) ->
|
||||||
{
|
{
|
||||||
LOGGER.warn("Parsing error: ["+newMessage+"]. " +
|
LOGGER.warn("Parsing error: ["+newMessage+"]. " +
|
||||||
@@ -576,6 +725,136 @@ public class ChunkLoader
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//====================//
|
||||||
|
// tag helper methods //
|
||||||
|
//====================//
|
||||||
|
|
||||||
|
// TODO move into separate file (this file is getting long)
|
||||||
|
// these tag helpers are to simplify tag accessing between MC versions
|
||||||
|
|
||||||
|
/** defaults to "false" if the tag isn't present */
|
||||||
|
private static boolean tagGetBoolean(CompoundTag tag, String key)
|
||||||
|
{
|
||||||
|
#if MC_VER < MC_1_21_5
|
||||||
|
return tag.getBoolean(key);
|
||||||
|
#else
|
||||||
|
return tag.getBoolean(key).orElse(false);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/** defaults to "0" if the tag isn't present */
|
||||||
|
private static byte tagGetByte(CompoundTag tag, String key)
|
||||||
|
{
|
||||||
|
#if MC_VER < MC_1_21_5
|
||||||
|
return tag.getByte(key);
|
||||||
|
#else
|
||||||
|
return tag.getByte(key).orElse((byte)0);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/** defaults to "0" if the tag isn't present */
|
||||||
|
private static short tagGetShort(ListTag tag, int index)
|
||||||
|
{
|
||||||
|
#if MC_VER < MC_1_21_5
|
||||||
|
return tag.getShort(index);
|
||||||
|
#else
|
||||||
|
return tag.getShort(index).orElse((short)0);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/** defaults to "0" if the tag isn't present */
|
||||||
|
private static int tagGetInt(CompoundTag tag, String key)
|
||||||
|
{
|
||||||
|
#if MC_VER < MC_1_21_5
|
||||||
|
return tag.getInt(key);
|
||||||
|
#else
|
||||||
|
return tag.getInt(key).orElse(0);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/** defaults to "0" if the tag isn't present */
|
||||||
|
private static long tagGetLong(CompoundTag tag, String key)
|
||||||
|
{
|
||||||
|
#if MC_VER < MC_1_21_5
|
||||||
|
return tag.getInt(key);
|
||||||
|
#else
|
||||||
|
return tag.getLong(key).orElse(0L);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/** defaults to null if the tag isn't present */
|
||||||
|
@Nullable
|
||||||
|
private static String tagGetString(CompoundTag tag, String key)
|
||||||
|
{
|
||||||
|
#if MC_VER < MC_1_21_5
|
||||||
|
return tag.getString(key);
|
||||||
|
#else
|
||||||
|
return tag.getString(key).orElse(null);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/** defaults to null if the tag isn't present */
|
||||||
|
@Nullable
|
||||||
|
private static byte[] tagGetByteArray(CompoundTag tag, String key)
|
||||||
|
{
|
||||||
|
#if MC_VER < MC_1_21_5
|
||||||
|
return tag.getByteArray(key);
|
||||||
|
#else
|
||||||
|
return tag.getByteArray(key).orElse(null);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/** defaults to null if the tag isn't present */
|
||||||
|
@Nullable
|
||||||
|
private static CompoundTag tagGetCompoundTag(CompoundTag tag, String key)
|
||||||
|
{
|
||||||
|
#if MC_VER < MC_1_21_5
|
||||||
|
return tag.getCompound(key);
|
||||||
|
#else
|
||||||
|
return tag.getCompound(key).orElse(null);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
/** defaults to null if the tag isn't present */
|
||||||
|
@Nullable
|
||||||
|
private static CompoundTag tagGetCompoundTag(ListTag tag, int index)
|
||||||
|
{
|
||||||
|
#if MC_VER < MC_1_21_5
|
||||||
|
return tag.getCompound(index);
|
||||||
|
#else
|
||||||
|
return tag.getCompound(index).orElse(null);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* defaults to null if the tag isn't present
|
||||||
|
* @param elementType unused after MC 1.21.5
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
private static ListTag tagGetListTag(CompoundTag tag, String key, int elementType)
|
||||||
|
{
|
||||||
|
#if MC_VER < MC_1_21_5
|
||||||
|
return tag.getList(key, elementType);
|
||||||
|
#else
|
||||||
|
return tag.getList(key).orElse(null);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/** defaults to null if the tag isn't present */
|
||||||
|
@Nullable
|
||||||
|
private static ListTag tagGetListTag(ListTag tag, int index)
|
||||||
|
{
|
||||||
|
#if MC_VER < MC_1_21_5
|
||||||
|
return tag.getList(index);
|
||||||
|
#else
|
||||||
|
return tag.getList(index).orElse(null);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//================//
|
//================//
|
||||||
// helper classes //
|
// helper classes //
|
||||||
+15
-6
@@ -28,7 +28,7 @@ import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
|||||||
import com.seibel.distanthorizons.core.util.LodUtil;
|
import com.seibel.distanthorizons.core.util.LodUtil;
|
||||||
import net.minecraft.world.level.block.EntityBlock;
|
import net.minecraft.world.level.block.EntityBlock;
|
||||||
import net.minecraft.world.level.block.SpawnerBlock;
|
import net.minecraft.world.level.block.SpawnerBlock;
|
||||||
import org.apache.logging.log4j.Logger;
|
import com.seibel.distanthorizons.core.logging.DhLogger;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
@@ -78,7 +78,7 @@ import net.minecraft.world.ticks.LevelTickAccess;
|
|||||||
|
|
||||||
public class DhLitWorldGenRegion extends WorldGenRegion
|
public class DhLitWorldGenRegion extends WorldGenRegion
|
||||||
{
|
{
|
||||||
private static final Logger LOGGER = DhLoggerBuilder.getLogger(MethodHandles.lookup().lookupClass().getSimpleName());
|
private static final DhLogger LOGGER = new DhLoggerBuilder().build();
|
||||||
|
|
||||||
private static ChunkStatus debugTriggeredForStatus = null;
|
private static ChunkStatus debugTriggeredForStatus = null;
|
||||||
|
|
||||||
@@ -229,8 +229,16 @@ public class DhLitWorldGenRegion extends WorldGenRegion
|
|||||||
{
|
{
|
||||||
ChunkAccess chunkAccess = this.getChunk(blockPos);
|
ChunkAccess chunkAccess = this.getChunk(blockPos);
|
||||||
if (chunkAccess instanceof LevelChunk)
|
if (chunkAccess instanceof LevelChunk)
|
||||||
|
{
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if MC_VER < MC_1_21_5
|
||||||
chunkAccess.setBlockState(blockPos, blockState, /*isBlockMoving*/false);
|
chunkAccess.setBlockState(blockPos, blockState, /*isBlockMoving*/false);
|
||||||
|
#else
|
||||||
|
chunkAccess.setBlockState(blockPos, blockState, /*flags*/0);
|
||||||
|
#endif
|
||||||
|
|
||||||
// This is for post ticking for water on gen and stuff like that. Not enabled
|
// This is for post ticking for water on gen and stuff like that. Not enabled
|
||||||
// for now.
|
// for now.
|
||||||
// if (blockState.hasPostProcess(this, blockPos))
|
// if (blockState.hasPostProcess(this, blockPos))
|
||||||
@@ -344,7 +352,7 @@ public class DhLitWorldGenRegion extends WorldGenRegion
|
|||||||
ChunkAccess chunk = this.getChunkAccess(chunkX, chunkZ, chunkStatus, returnNonNull);
|
ChunkAccess chunk = this.getChunkAccess(chunkX, chunkZ, chunkStatus, returnNonNull);
|
||||||
if (chunk instanceof LevelChunk)
|
if (chunk instanceof LevelChunk)
|
||||||
{
|
{
|
||||||
chunk = new ImposterProtoChunk((LevelChunk) chunk #if MC_VER >= MC_1_18_2 , true #endif );
|
chunk = new ImposterProtoChunk((LevelChunk) chunk #if MC_VER >= MC_1_18_2 ,/* allow writes */ false #endif );
|
||||||
}
|
}
|
||||||
return chunk;
|
return chunk;
|
||||||
}
|
}
|
||||||
@@ -384,10 +392,11 @@ public class DhLitWorldGenRegion extends WorldGenRegion
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (chunkStatus != ChunkStatus.EMPTY && chunkStatus != debugTriggeredForStatus)
|
if (chunkStatus != ChunkStatus.EMPTY
|
||||||
|
&& chunkStatus != debugTriggeredForStatus)
|
||||||
{
|
{
|
||||||
LOGGER.info("WorldGen requiring " + chunkStatus
|
LOGGER.info("WorldGen requiring [" + chunkStatus + "]"
|
||||||
+ " outside expected range detected. Force passing EMPTY chunk and seeing if it works.");
|
+ " is outside the expected range. Returning EMPTY chunk.");
|
||||||
debugTriggeredForStatus = chunkStatus;
|
debugTriggeredForStatus = chunkStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+3
-3
@@ -7,7 +7,7 @@ import net.minecraft.nbt.NbtIo;
|
|||||||
import net.minecraft.world.level.ChunkPos;
|
import net.minecraft.world.level.ChunkPos;
|
||||||
import net.minecraft.world.level.chunk.storage.RegionFile;
|
import net.minecraft.world.level.chunk.storage.RegionFile;
|
||||||
import net.minecraft.world.level.chunk.storage.RegionFileStorage;
|
import net.minecraft.world.level.chunk.storage.RegionFileStorage;
|
||||||
import org.apache.logging.log4j.Logger;
|
import com.seibel.distanthorizons.core.logging.DhLogger;
|
||||||
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import java.io.DataInputStream;
|
import java.io.DataInputStream;
|
||||||
@@ -29,7 +29,7 @@ import net.minecraft.world.level.chunk.storage.RegionStorageInfo;
|
|||||||
*/
|
*/
|
||||||
public class RegionFileStorageExternalCache implements AutoCloseable
|
public class RegionFileStorageExternalCache implements AutoCloseable
|
||||||
{
|
{
|
||||||
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
|
private static final DhLogger LOGGER = new DhLoggerBuilder().build();
|
||||||
|
|
||||||
/** Can be null due to the C2ME mod */
|
/** Can be null due to the C2ME mod */
|
||||||
@Nullable
|
@Nullable
|
||||||
@@ -139,7 +139,7 @@ public class RegionFileStorageExternalCache implements AutoCloseable
|
|||||||
|
|
||||||
if (retryCount >= maxRetryCount)
|
if (retryCount >= maxRetryCount)
|
||||||
{
|
{
|
||||||
BatchGenerationEnvironment.LOAD_LOGGER.warn("Concurrency issue detected when getting region file for chunk at [" + pos + "].");
|
BatchGenerationEnvironment.CHUNK_LOAD_LOGGER.warn("Concurrency issue detected when getting region file for chunk at [" + pos + "].");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+54
@@ -0,0 +1,54 @@
|
|||||||
|
package com.seibel.distanthorizons.common.wrappers.worldGeneration.step;
|
||||||
|
|
||||||
|
import com.seibel.distanthorizons.common.wrappers.chunk.ChunkWrapper;
|
||||||
|
import com.seibel.distanthorizons.common.wrappers.worldGeneration.ThreadedParameters;
|
||||||
|
import com.seibel.distanthorizons.common.wrappers.worldGeneration.mimicObject.DhLitWorldGenRegion;
|
||||||
|
import com.seibel.distanthorizons.core.util.gridList.ArrayGridList;
|
||||||
|
import net.minecraft.world.level.chunk.ChunkAccess;
|
||||||
|
import net.minecraft.world.level.chunk.ProtoChunk;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
#if MC_VER <= MC_1_20_4
|
||||||
|
import net.minecraft.world.level.chunk.ChunkStatus;
|
||||||
|
#else
|
||||||
|
import net.minecraft.world.level.chunk.status.ChunkStatus;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
public abstract class AbstractWorldGenStep
|
||||||
|
{
|
||||||
|
public abstract void generateGroup(
|
||||||
|
ThreadedParameters tParams, DhLitWorldGenRegion worldGenRegion,
|
||||||
|
ArrayGridList<ChunkWrapper> chunkWrappers);
|
||||||
|
|
||||||
|
public abstract ChunkStatus getChunkStatus();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/** @return the list of chunks that have an earlier status and can be generated */
|
||||||
|
protected ArrayList<ChunkAccess> getChunksToGenerate(List<ChunkWrapper> chunkWrappers)
|
||||||
|
{
|
||||||
|
ArrayList<ChunkAccess> chunksToGenerate = new ArrayList<>();
|
||||||
|
|
||||||
|
for (ChunkWrapper chunkWrapper : chunkWrappers)
|
||||||
|
{
|
||||||
|
ChunkAccess chunk = chunkWrapper.getChunk();
|
||||||
|
if (chunkWrapper.getStatus().isOrAfter(this.getChunkStatus()))
|
||||||
|
{
|
||||||
|
// this chunk has already generated this step
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if (chunk instanceof ProtoChunk)
|
||||||
|
{
|
||||||
|
chunkWrapper.trySetStatus(this.getChunkStatus());
|
||||||
|
chunksToGenerate.add(chunk);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return chunksToGenerate;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
+21
-24
@@ -20,12 +20,13 @@
|
|||||||
package com.seibel.distanthorizons.common.wrappers.worldGeneration.step;
|
package com.seibel.distanthorizons.common.wrappers.worldGeneration.step;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import com.seibel.distanthorizons.common.wrappers.chunk.ChunkWrapper;
|
import com.seibel.distanthorizons.common.wrappers.chunk.ChunkWrapper;
|
||||||
import com.seibel.distanthorizons.common.wrappers.worldGeneration.BatchGenerationEnvironment;
|
import com.seibel.distanthorizons.common.wrappers.worldGeneration.BatchGenerationEnvironment;
|
||||||
import com.seibel.distanthorizons.common.wrappers.worldGeneration.ThreadedParameters;
|
import com.seibel.distanthorizons.common.wrappers.worldGeneration.ThreadedParameters;
|
||||||
|
|
||||||
|
import com.seibel.distanthorizons.common.wrappers.worldGeneration.mimicObject.DhLitWorldGenRegion;
|
||||||
|
import com.seibel.distanthorizons.core.util.gridList.ArrayGridList;
|
||||||
import net.minecraft.server.level.WorldGenRegion;
|
import net.minecraft.server.level.WorldGenRegion;
|
||||||
import net.minecraft.world.level.chunk.ChunkAccess;
|
import net.minecraft.world.level.chunk.ChunkAccess;
|
||||||
import net.minecraft.world.level.chunk.ProtoChunk;
|
import net.minecraft.world.level.chunk.ProtoChunk;
|
||||||
@@ -40,39 +41,35 @@ import net.minecraft.world.level.chunk.ChunkStatus;
|
|||||||
import net.minecraft.world.level.chunk.status.ChunkStatus;
|
import net.minecraft.world.level.chunk.status.ChunkStatus;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
public final class StepBiomes
|
public final class StepBiomes extends AbstractWorldGenStep
|
||||||
{
|
{
|
||||||
public static final ChunkStatus STATUS = ChunkStatus.BIOMES;
|
|
||||||
|
|
||||||
private final BatchGenerationEnvironment environment;
|
private final BatchGenerationEnvironment environment;
|
||||||
|
|
||||||
|
public static final ChunkStatus STATUS = ChunkStatus.BIOMES;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//=============//
|
||||||
|
// constructor //
|
||||||
|
//=============//
|
||||||
|
|
||||||
public StepBiomes(BatchGenerationEnvironment batchGenerationEnvironment) { this.environment = batchGenerationEnvironment; }
|
public StepBiomes(BatchGenerationEnvironment batchGenerationEnvironment) { this.environment = batchGenerationEnvironment; }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//==================//
|
||||||
|
// abstract methods //
|
||||||
|
//==================//
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ChunkStatus getChunkStatus() { return STATUS; }
|
||||||
|
|
||||||
|
@Override
|
||||||
public void generateGroup(
|
public void generateGroup(
|
||||||
ThreadedParameters tParams, WorldGenRegion worldGenRegion,
|
ThreadedParameters tParams, DhLitWorldGenRegion worldGenRegion,
|
||||||
List<ChunkWrapper> chunkWrappers)
|
ArrayGridList<ChunkWrapper> chunkWrappers)
|
||||||
{
|
{
|
||||||
|
ArrayList<ChunkAccess> chunksToDo = this.getChunksToGenerate(chunkWrappers);
|
||||||
ArrayList<ChunkAccess> chunksToDo = new ArrayList<>();
|
|
||||||
|
|
||||||
for (ChunkWrapper chunkWrapper : chunkWrappers)
|
|
||||||
{
|
|
||||||
ChunkAccess chunk = chunkWrapper.getChunk();
|
|
||||||
if (chunkWrapper.getStatus().isOrAfter(STATUS))
|
|
||||||
{
|
|
||||||
// this chunk has already generated this step
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else if (chunk instanceof ProtoChunk)
|
|
||||||
{
|
|
||||||
chunkWrapper.trySetStatus(STATUS);
|
|
||||||
chunksToDo.add(chunk);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (ChunkAccess chunk : chunksToDo)
|
for (ChunkAccess chunk : chunksToDo)
|
||||||
{
|
{
|
||||||
#if MC_VER < MC_1_18_2
|
#if MC_VER < MC_1_18_2
|
||||||
|
|||||||
+21
-3
@@ -29,7 +29,7 @@ import com.seibel.distanthorizons.core.util.gridList.ArrayGridList;
|
|||||||
import net.minecraft.world.level.chunk.ChunkAccess;
|
import net.minecraft.world.level.chunk.ChunkAccess;
|
||||||
import net.minecraft.world.level.chunk.ProtoChunk;
|
import net.minecraft.world.level.chunk.ProtoChunk;
|
||||||
import net.minecraft.world.level.levelgen.Heightmap;
|
import net.minecraft.world.level.levelgen.Heightmap;
|
||||||
import org.apache.logging.log4j.Logger;
|
import com.seibel.distanthorizons.core.logging.DhLogger;
|
||||||
|
|
||||||
#if MC_VER <= MC_1_20_4
|
#if MC_VER <= MC_1_20_4
|
||||||
import net.minecraft.world.level.chunk.ChunkStatus;
|
import net.minecraft.world.level.chunk.ChunkStatus;
|
||||||
@@ -37,10 +37,12 @@ import net.minecraft.world.level.chunk.ChunkStatus;
|
|||||||
import net.minecraft.world.level.chunk.status.ChunkStatus;
|
import net.minecraft.world.level.chunk.status.ChunkStatus;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
import java.util.ConcurrentModificationException;
|
||||||
|
|
||||||
public final class StepFeatures
|
|
||||||
|
public final class StepFeatures extends AbstractWorldGenStep
|
||||||
{
|
{
|
||||||
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
|
private static final DhLogger LOGGER = new DhLoggerBuilder().build();
|
||||||
|
|
||||||
public static final ChunkStatus STATUS = ChunkStatus.FEATURES;
|
public static final ChunkStatus STATUS = ChunkStatus.FEATURES;
|
||||||
|
|
||||||
@@ -48,10 +50,22 @@ public final class StepFeatures
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//=============//
|
||||||
|
// constructor //
|
||||||
|
//=============//
|
||||||
|
|
||||||
public StepFeatures(BatchGenerationEnvironment batchGenerationEnvironment) { this.environment = batchGenerationEnvironment; }
|
public StepFeatures(BatchGenerationEnvironment batchGenerationEnvironment) { this.environment = batchGenerationEnvironment; }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//==================//
|
||||||
|
// abstract methods //
|
||||||
|
//==================//
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ChunkStatus getChunkStatus() { return STATUS; }
|
||||||
|
|
||||||
|
@Override
|
||||||
public void generateGroup(
|
public void generateGroup(
|
||||||
ThreadedParameters tParams, DhLitWorldGenRegion worldGenRegion,
|
ThreadedParameters tParams, DhLitWorldGenRegion worldGenRegion,
|
||||||
ArrayGridList<ChunkWrapper> chunkWrappers)
|
ArrayGridList<ChunkWrapper> chunkWrappers)
|
||||||
@@ -88,6 +102,10 @@ public final class StepFeatures
|
|||||||
|
|
||||||
Heightmap.primeHeightmaps(chunk, STATUS.heightmapsAfter());
|
Heightmap.primeHeightmaps(chunk, STATUS.heightmapsAfter());
|
||||||
}
|
}
|
||||||
|
catch (ConcurrentModificationException e) // ReportedException
|
||||||
|
{
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
LOGGER.warn("Unexpected issue when generating features for chunk at pos ["+chunkWrapper.getChunkPos()+"], error: ["+e.getMessage()+"].", e);
|
LOGGER.warn("Unexpected issue when generating features for chunk at pos ["+chunkWrapper.getChunkPos()+"], error: ["+e.getMessage()+"].", e);
|
||||||
|
|||||||
+17
-4
@@ -26,6 +26,8 @@ import com.seibel.distanthorizons.common.wrappers.chunk.ChunkWrapper;
|
|||||||
import com.seibel.distanthorizons.common.wrappers.worldGeneration.BatchGenerationEnvironment;
|
import com.seibel.distanthorizons.common.wrappers.worldGeneration.BatchGenerationEnvironment;
|
||||||
import com.seibel.distanthorizons.common.wrappers.worldGeneration.ThreadedParameters;
|
import com.seibel.distanthorizons.common.wrappers.worldGeneration.ThreadedParameters;
|
||||||
|
|
||||||
|
import com.seibel.distanthorizons.common.wrappers.worldGeneration.mimicObject.DhLitWorldGenRegion;
|
||||||
|
import com.seibel.distanthorizons.core.util.gridList.ArrayGridList;
|
||||||
import com.seibel.distanthorizons.core.util.objects.UncheckedInterruptedException;
|
import com.seibel.distanthorizons.core.util.objects.UncheckedInterruptedException;
|
||||||
import net.minecraft.server.level.WorldGenRegion;
|
import net.minecraft.server.level.WorldGenRegion;
|
||||||
import net.minecraft.world.level.chunk.ChunkAccess;
|
import net.minecraft.world.level.chunk.ChunkAccess;
|
||||||
@@ -41,7 +43,7 @@ import net.minecraft.world.level.chunk.ChunkStatus;
|
|||||||
import net.minecraft.world.level.chunk.status.ChunkStatus;
|
import net.minecraft.world.level.chunk.status.ChunkStatus;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
public final class StepNoise
|
public final class StepNoise extends AbstractWorldGenStep
|
||||||
{
|
{
|
||||||
private static final ChunkStatus STATUS = ChunkStatus.NOISE;
|
private static final ChunkStatus STATUS = ChunkStatus.NOISE;
|
||||||
|
|
||||||
@@ -49,15 +51,26 @@ public final class StepNoise
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//=============//
|
||||||
|
// constructor //
|
||||||
|
//=============//
|
||||||
|
|
||||||
public StepNoise(BatchGenerationEnvironment batchGenerationEnvironment) { this.environment = batchGenerationEnvironment; }
|
public StepNoise(BatchGenerationEnvironment batchGenerationEnvironment) { this.environment = batchGenerationEnvironment; }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//==================//
|
||||||
|
// abstract methods //
|
||||||
|
//==================//
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ChunkStatus getChunkStatus() { return STATUS; }
|
||||||
|
|
||||||
|
@Override
|
||||||
public void generateGroup(
|
public void generateGroup(
|
||||||
ThreadedParameters tParams, WorldGenRegion worldGenRegion,
|
ThreadedParameters tParams, DhLitWorldGenRegion worldGenRegion,
|
||||||
List<ChunkWrapper> chunkWrappers)
|
ArrayGridList<ChunkWrapper> chunkWrappers)
|
||||||
{
|
{
|
||||||
|
|
||||||
ArrayList<ChunkAccess> chunksToDo = new ArrayList<>();
|
ArrayList<ChunkAccess> chunksToDo = new ArrayList<>();
|
||||||
|
|
||||||
for (ChunkWrapper chunkWrapper : chunkWrappers)
|
for (ChunkWrapper chunkWrapper : chunkWrappers)
|
||||||
|
|||||||
+18
-4
@@ -26,6 +26,8 @@ import com.seibel.distanthorizons.common.wrappers.chunk.ChunkWrapper;
|
|||||||
import com.seibel.distanthorizons.common.wrappers.worldGeneration.BatchGenerationEnvironment;
|
import com.seibel.distanthorizons.common.wrappers.worldGeneration.BatchGenerationEnvironment;
|
||||||
import com.seibel.distanthorizons.common.wrappers.worldGeneration.ThreadedParameters;
|
import com.seibel.distanthorizons.common.wrappers.worldGeneration.ThreadedParameters;
|
||||||
|
|
||||||
|
import com.seibel.distanthorizons.common.wrappers.worldGeneration.mimicObject.DhLitWorldGenRegion;
|
||||||
|
import com.seibel.distanthorizons.core.util.gridList.ArrayGridList;
|
||||||
import net.minecraft.server.level.WorldGenRegion;
|
import net.minecraft.server.level.WorldGenRegion;
|
||||||
import net.minecraft.world.level.chunk.ChunkAccess;
|
import net.minecraft.world.level.chunk.ChunkAccess;
|
||||||
import net.minecraft.world.level.chunk.ProtoChunk;
|
import net.minecraft.world.level.chunk.ProtoChunk;
|
||||||
@@ -37,7 +39,7 @@ import net.minecraft.world.level.chunk.status.ChunkStatus;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
public final class StepStructureReference
|
public final class StepStructureReference extends AbstractWorldGenStep
|
||||||
{
|
{
|
||||||
private static final ChunkStatus STATUS = ChunkStatus.STRUCTURE_REFERENCES;
|
private static final ChunkStatus STATUS = ChunkStatus.STRUCTURE_REFERENCES;
|
||||||
|
|
||||||
@@ -45,15 +47,26 @@ public final class StepStructureReference
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//=============//
|
||||||
|
// constructor //
|
||||||
|
//=============//
|
||||||
|
|
||||||
public StepStructureReference(BatchGenerationEnvironment batchGenerationEnvironment) { this.environment = batchGenerationEnvironment; }
|
public StepStructureReference(BatchGenerationEnvironment batchGenerationEnvironment) { this.environment = batchGenerationEnvironment; }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//==================//
|
||||||
|
// abstract methods //
|
||||||
|
//==================//
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ChunkStatus getChunkStatus() { return STATUS; }
|
||||||
|
|
||||||
|
@Override
|
||||||
public void generateGroup(
|
public void generateGroup(
|
||||||
ThreadedParameters tParams, WorldGenRegion worldGenRegion,
|
ThreadedParameters tParams, DhLitWorldGenRegion worldGenRegion,
|
||||||
List<ChunkWrapper> chunkWrappers)
|
ArrayGridList<ChunkWrapper> chunkWrappers)
|
||||||
{
|
{
|
||||||
|
|
||||||
ArrayList<ChunkAccess> chunksToDo = new ArrayList<ChunkAccess>();
|
ArrayList<ChunkAccess> chunksToDo = new ArrayList<ChunkAccess>();
|
||||||
|
|
||||||
for (ChunkWrapper chunkWrapper : chunkWrappers)
|
for (ChunkWrapper chunkWrapper : chunkWrappers)
|
||||||
@@ -67,6 +80,7 @@ public final class StepStructureReference
|
|||||||
else if (chunk instanceof ProtoChunk)
|
else if (chunk instanceof ProtoChunk)
|
||||||
{
|
{
|
||||||
chunkWrapper.trySetStatus(STATUS);
|
chunkWrapper.trySetStatus(STATUS);
|
||||||
|
chunksToDo.add(chunk);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+19
-40
@@ -27,13 +27,15 @@ import com.seibel.distanthorizons.common.wrappers.chunk.ChunkWrapper;
|
|||||||
import com.seibel.distanthorizons.common.wrappers.worldGeneration.BatchGenerationEnvironment;
|
import com.seibel.distanthorizons.common.wrappers.worldGeneration.BatchGenerationEnvironment;
|
||||||
import com.seibel.distanthorizons.common.wrappers.worldGeneration.ThreadedParameters;
|
import com.seibel.distanthorizons.common.wrappers.worldGeneration.ThreadedParameters;
|
||||||
|
|
||||||
|
import com.seibel.distanthorizons.common.wrappers.worldGeneration.mimicObject.DhLitWorldGenRegion;
|
||||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||||
|
import com.seibel.distanthorizons.core.util.gridList.ArrayGridList;
|
||||||
import net.minecraft.resources.ResourceKey;
|
import net.minecraft.resources.ResourceKey;
|
||||||
import net.minecraft.server.level.WorldGenRegion;
|
import net.minecraft.server.level.WorldGenRegion;
|
||||||
import net.minecraft.world.level.Level;
|
import net.minecraft.world.level.Level;
|
||||||
import net.minecraft.world.level.chunk.ChunkAccess;
|
import net.minecraft.world.level.chunk.ChunkAccess;
|
||||||
import net.minecraft.world.level.chunk.ProtoChunk;
|
import net.minecraft.world.level.chunk.ProtoChunk;
|
||||||
import org.apache.logging.log4j.Logger;
|
import com.seibel.distanthorizons.core.logging.DhLogger;
|
||||||
|
|
||||||
#if MC_VER <= MC_1_20_4
|
#if MC_VER <= MC_1_20_4
|
||||||
import net.minecraft.world.level.chunk.ChunkStatus;
|
import net.minecraft.world.level.chunk.ChunkStatus;
|
||||||
@@ -42,9 +44,9 @@ import net.minecraft.world.level.chunk.status.ChunkStatus;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
public final class StepStructureStart
|
public final class StepStructureStart extends AbstractWorldGenStep
|
||||||
{
|
{
|
||||||
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
|
private static final DhLogger LOGGER = new DhLoggerBuilder().build();
|
||||||
private static final ChunkStatus STATUS = ChunkStatus.STRUCTURE_STARTS;
|
private static final ChunkStatus STATUS = ChunkStatus.STRUCTURE_STARTS;
|
||||||
private static final ReentrantLock STRUCTURE_PLACEMENT_LOCK = new ReentrantLock();
|
private static final ReentrantLock STRUCTURE_PLACEMENT_LOCK = new ReentrantLock();
|
||||||
|
|
||||||
@@ -52,42 +54,27 @@ public final class StepStructureStart
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//=============//
|
||||||
|
// constructor //
|
||||||
|
//=============//
|
||||||
|
|
||||||
public StepStructureStart(BatchGenerationEnvironment batchGenerationEnvironment) { this.environment = batchGenerationEnvironment; }
|
public StepStructureStart(BatchGenerationEnvironment batchGenerationEnvironment) { this.environment = batchGenerationEnvironment; }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static class StructStartCorruptedException extends RuntimeException
|
//==================//
|
||||||
{
|
// abstract methods //
|
||||||
private static final long serialVersionUID = -8987434342051563358L;
|
//==================//
|
||||||
|
|
||||||
public StructStartCorruptedException(ArrayIndexOutOfBoundsException e)
|
|
||||||
{
|
|
||||||
super("StructStartCorruptedException");
|
|
||||||
super.initCause(e);
|
|
||||||
fillInStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ChunkStatus getChunkStatus() { return STATUS; }
|
||||||
|
|
||||||
|
@Override
|
||||||
public void generateGroup(
|
public void generateGroup(
|
||||||
ThreadedParameters tParams, WorldGenRegion worldGenRegion,
|
ThreadedParameters tParams, DhLitWorldGenRegion worldGenRegion,
|
||||||
List<ChunkWrapper> chunkWrappers) throws InterruptedException
|
ArrayGridList<ChunkWrapper> chunkWrappers)
|
||||||
{
|
{
|
||||||
ArrayList<ChunkAccess> chunksToDo = new ArrayList<>();
|
ArrayList<ChunkAccess> chunksToDo = this.getChunksToGenerate(chunkWrappers);
|
||||||
|
|
||||||
for (ChunkWrapper chunkWrapper : chunkWrappers)
|
|
||||||
{
|
|
||||||
ChunkAccess chunk = chunkWrapper.getChunk();
|
|
||||||
if (chunkWrapper.getStatus().isOrAfter(STATUS))
|
|
||||||
{
|
|
||||||
// this chunk has already generated this step
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else if (chunk instanceof ProtoChunk)
|
|
||||||
{
|
|
||||||
chunkWrapper.trySetStatus(STATUS);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#if MC_VER < MC_1_19_2
|
#if MC_VER < MC_1_19_2
|
||||||
if (this.environment.params.worldGenSettings.generateFeatures())
|
if (this.environment.params.worldGenSettings.generateFeatures())
|
||||||
@@ -101,12 +88,6 @@ public final class StepStructureStart
|
|||||||
#endif
|
#endif
|
||||||
for (ChunkAccess chunk : chunksToDo)
|
for (ChunkAccess chunk : chunksToDo)
|
||||||
{
|
{
|
||||||
// System.out.println("StepStructureStart: "+chunk.getPos());
|
|
||||||
|
|
||||||
// there are a few cases where the structure generator call may lock up (either due to teleporting or leaving the world).
|
|
||||||
// hopefully allowing interrupts here will prevent that from happening.
|
|
||||||
BatchGenerationEnvironment.throwIfThreadInterrupted();
|
|
||||||
|
|
||||||
// hopefully this shouldn't cause any performance issues (this step is generally quite quick so hopefully it should be fine)
|
// hopefully this shouldn't cause any performance issues (this step is generally quite quick so hopefully it should be fine)
|
||||||
// and should prevent some concurrency issues
|
// and should prevent some concurrency issues
|
||||||
STRUCTURE_PLACEMENT_LOCK.lock();
|
STRUCTURE_PLACEMENT_LOCK.lock();
|
||||||
@@ -151,8 +132,6 @@ public final class StepStructureStart
|
|||||||
{
|
{
|
||||||
// the structure logic failed again, log it and move on
|
// the structure logic failed again, log it and move on
|
||||||
LOGGER.error("Unable to create structure starts for " + chunk.getPos() + ". This is an error with MC's world generation. Ignoring and continuing generation. Error: " + secondEx.getMessage()); // don't log the full stack trace since it is long and will generally end up in MC's code
|
LOGGER.error("Unable to create structure starts for " + chunk.getPos() + ". This is an error with MC's world generation. Ignoring and continuing generation. Error: " + secondEx.getMessage()); // don't log the full stack trace since it is long and will generally end up in MC's code
|
||||||
|
|
||||||
//throw new StepStructureStart.StructStartCorruptedException(secondEx);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+17
-3
@@ -26,6 +26,8 @@ import com.seibel.distanthorizons.common.wrappers.chunk.ChunkWrapper;
|
|||||||
import com.seibel.distanthorizons.common.wrappers.worldGeneration.BatchGenerationEnvironment;
|
import com.seibel.distanthorizons.common.wrappers.worldGeneration.BatchGenerationEnvironment;
|
||||||
import com.seibel.distanthorizons.common.wrappers.worldGeneration.ThreadedParameters;
|
import com.seibel.distanthorizons.common.wrappers.worldGeneration.ThreadedParameters;
|
||||||
|
|
||||||
|
import com.seibel.distanthorizons.common.wrappers.worldGeneration.mimicObject.DhLitWorldGenRegion;
|
||||||
|
import com.seibel.distanthorizons.core.util.gridList.ArrayGridList;
|
||||||
import net.minecraft.server.level.WorldGenRegion;
|
import net.minecraft.server.level.WorldGenRegion;
|
||||||
import net.minecraft.world.level.chunk.ChunkAccess;
|
import net.minecraft.world.level.chunk.ChunkAccess;
|
||||||
import net.minecraft.world.level.chunk.ProtoChunk;
|
import net.minecraft.world.level.chunk.ProtoChunk;
|
||||||
@@ -37,7 +39,7 @@ import net.minecraft.world.level.chunk.status.ChunkStatus;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
public final class StepSurface
|
public final class StepSurface extends AbstractWorldGenStep
|
||||||
{
|
{
|
||||||
private static final ChunkStatus STATUS = ChunkStatus.SURFACE;
|
private static final ChunkStatus STATUS = ChunkStatus.SURFACE;
|
||||||
|
|
||||||
@@ -45,13 +47,25 @@ public final class StepSurface
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//=============//
|
||||||
|
// constructor //
|
||||||
|
//=============//
|
||||||
|
|
||||||
public StepSurface(BatchGenerationEnvironment batchGenerationEnvironment) { this.environment = batchGenerationEnvironment; }
|
public StepSurface(BatchGenerationEnvironment batchGenerationEnvironment) { this.environment = batchGenerationEnvironment; }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//==================//
|
||||||
|
// abstract methods //
|
||||||
|
//==================//
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ChunkStatus getChunkStatus() { return STATUS; }
|
||||||
|
|
||||||
|
@Override
|
||||||
public void generateGroup(
|
public void generateGroup(
|
||||||
ThreadedParameters tParams, WorldGenRegion worldGenRegion,
|
ThreadedParameters tParams, DhLitWorldGenRegion worldGenRegion,
|
||||||
List<ChunkWrapper> chunkWrappers)
|
ArrayGridList<ChunkWrapper> chunkWrappers)
|
||||||
{
|
{
|
||||||
ArrayList<ChunkAccess> chunksToDo = new ArrayList<>();
|
ArrayList<ChunkAccess> chunksToDo = new ArrayList<>();
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,54 @@
|
|||||||
|
accessWidener v1 named
|
||||||
|
|
||||||
|
# used when determining where to save files to
|
||||||
|
accessible field net/minecraft/world/level/storage/DimensionDataStorage dataFolder Ljava/nio/file/Path;
|
||||||
|
# used to help determine what folder a clientLevel is
|
||||||
|
accessible field net/minecraft/world/level/biome/BiomeManager biomeZoomSeed J
|
||||||
|
|
||||||
|
# used when rendering
|
||||||
|
accessible method net/minecraft/client/renderer/GameRenderer getFov (Lnet/minecraft/client/Camera;FZ)F
|
||||||
|
accessible field net/minecraft/client/Minecraft deltaTracker Lnet/minecraft/client/DeltaTracker$Timer;
|
||||||
|
accessible field net/minecraft/client/renderer/LevelRenderer level Lnet/minecraft/client/multiplayer/ClientLevel;
|
||||||
|
|
||||||
|
|
||||||
|
# used for grabbing vanilla rendered chunks
|
||||||
|
accessible field net/minecraft/client/renderer/LevelRenderer visibleSections Lit/unimi/dsi/fastutil/objects/ObjectArrayList;
|
||||||
|
|
||||||
|
# world generation
|
||||||
|
# accessible method net/minecraft/world/level/lighting/LayerLightEngine queueSectionData (JLnet/minecraft/world/level/chunk/DataLayer;Z)V
|
||||||
|
accessible field net/minecraft/world/level/chunk/LevelChunk loaded Z
|
||||||
|
accessible field net/minecraft/world/level/lighting/LightEngine storage Lnet/minecraft/world/level/lighting/LayerLightSectionStorage;
|
||||||
|
accessible method net/minecraft/world/level/lighting/LayerLightSectionStorage lightOnInSection (J)Z
|
||||||
|
accessible field net/minecraft/server/level/ServerChunkCache distanceManager Lnet/minecraft/server/level/DistanceManager;
|
||||||
|
accessible method net/minecraft/server/level/ChunkMap getUpdatingChunkIfPresent (J)Lnet/minecraft/server/level/ChunkHolder;
|
||||||
|
accessible method net/minecraft/server/level/ChunkMap tick (Ljava/util/function/BooleanSupplier;)V
|
||||||
|
accessible field net/minecraft/server/level/ServerLevel entityManager Lnet/minecraft/world/level/entity/PersistentEntitySectionManager;
|
||||||
|
accessible field net/minecraft/server/level/ChunkMap mainThreadExecutor Lnet/minecraft/util/thread/BlockableEventLoop;
|
||||||
|
|
||||||
|
# lod generation from save file
|
||||||
|
accessible field net/minecraft/world/level/chunk/storage/ChunkStorage worker Lnet/minecraft/world/level/chunk/storage/IOWorker;
|
||||||
|
accessible field net/minecraft/world/level/chunk/storage/IOWorker storage Lnet/minecraft/world/level/chunk/storage/RegionFileStorage;
|
||||||
|
accessible field net/minecraft/world/level/chunk/storage/RegionFileStorage regionCache Lit/unimi/dsi/fastutil/longs/Long2ObjectLinkedOpenHashMap;
|
||||||
|
accessible field net/minecraft/world/level/chunk/storage/RegionFileStorage folder Ljava/nio/file/Path;
|
||||||
|
|
||||||
|
# grabbing textures
|
||||||
|
accessible class net/minecraft/client/renderer/texture/SpriteContents$AnimatedTexture
|
||||||
|
accessible method net/minecraft/client/renderer/texture/SpriteContents$AnimatedTexture getFrameX (I)I
|
||||||
|
accessible method net/minecraft/client/renderer/texture/SpriteContents$AnimatedTexture getFrameY (I)I
|
||||||
|
accessible field net/minecraft/client/renderer/texture/SpriteContents animatedTexture Lnet/minecraft/client/renderer/texture/SpriteContents$AnimatedTexture;
|
||||||
|
accessible field net/minecraft/client/renderer/texture/SpriteContents originalImage Lcom/mojang/blaze3d/platform/NativeImage;
|
||||||
|
|
||||||
|
# UI stuff
|
||||||
|
accessible field net/minecraft/client/gui/components/AbstractButton SPRITES Lnet/minecraft/client/gui/components/WidgetSprites;
|
||||||
|
# Handles inserting the config button
|
||||||
|
accessible field net/minecraft/client/gui/layouts/HeaderAndFooterLayout headerFrame Lnet/minecraft/client/gui/layouts/FrameLayout;
|
||||||
|
accessible field net/minecraft/client/gui/layouts/FrameLayout children Ljava/util/List;
|
||||||
|
accessible class net/minecraft/client/gui/layouts/FrameLayout$ChildContainer
|
||||||
|
accessible field net/minecraft/client/gui/layouts/LinearLayout wrapped Lnet/minecraft/client/gui/layouts/GridLayout;
|
||||||
|
accessible method net/minecraft/client/gui/components/debug/DebugScreenEntries register (Lnet/minecraft/resources/ResourceLocation;Lnet/minecraft/client/gui/components/debug/DebugScreenEntry;)Lnet/minecraft/resources/ResourceLocation;
|
||||||
|
|
||||||
|
# hacky stuff
|
||||||
|
accessible field net/minecraft/util/ThreadingDetector lock Ljava/util/concurrent/Semaphore;
|
||||||
|
mutable field net/minecraft/util/ThreadingDetector lock Ljava/util/concurrent/Semaphore;
|
||||||
|
|
||||||
|
|
||||||
+1
-1
Submodule coreSubProjects updated: f9bd7e2daf...b82a59ecbc
+52
-8
@@ -1,5 +1,5 @@
|
|||||||
plugins {
|
plugins {
|
||||||
id "fabric-loom" version "1.8-SNAPSHOT"
|
id "fabric-loom" version "1.10-SNAPSHOT"
|
||||||
}
|
}
|
||||||
|
|
||||||
loom {
|
loom {
|
||||||
@@ -19,7 +19,9 @@ loom {
|
|||||||
"-Dminecraft.api.session.host=https://nope.invalid",
|
"-Dminecraft.api.session.host=https://nope.invalid",
|
||||||
"-Dminecraft.api.services.host=https://nope.invalid",
|
"-Dminecraft.api.services.host=https://nope.invalid",
|
||||||
// https://netty.io/wiki/reference-counted-objects.html#leak-detection-levels
|
// https://netty.io/wiki/reference-counted-objects.html#leak-detection-levels
|
||||||
"-Dio.netty.leakDetection.level=advanced"
|
"-Dio.netty.leakDetection.level=advanced",
|
||||||
|
"-XX:+UseZGC",
|
||||||
|
"-XX:+ZGenerational"
|
||||||
)
|
)
|
||||||
programArgs("--username", "Dev")
|
programArgs("--username", "Dev")
|
||||||
}
|
}
|
||||||
@@ -72,19 +74,27 @@ dependencies {
|
|||||||
// runtimeOnly "javax.annotation:javax.annotation-api:1.3.2"
|
// runtimeOnly "javax.annotation:javax.annotation-api:1.3.2"
|
||||||
// compileOnly "javax.annotation:javax.annotation-api:1.3.2"
|
// compileOnly "javax.annotation:javax.annotation-api:1.3.2"
|
||||||
// modImplementation "javax.annotation:javax.annotation-api:1.3.2"
|
// modImplementation "javax.annotation:javax.annotation-api:1.3.2"
|
||||||
|
|
||||||
// Fabric API
|
// Fabric API
|
||||||
addModJar(fabricApi.module("fabric-api-base", rootProject.fabric_api_version))
|
addModJar(fabricApi.module("fabric-api-base", rootProject.fabric_api_version))
|
||||||
addModJar(fabricApi.module("fabric-lifecycle-events-v1", rootProject.fabric_api_version))
|
addModJar(fabricApi.module("fabric-lifecycle-events-v1", rootProject.fabric_api_version))
|
||||||
addModJar(fabricApi.module("fabric-resource-loader-v0", rootProject.fabric_api_version))
|
if (buildVersionBefore(minecraft_version, "1.21.9"))
|
||||||
|
{
|
||||||
|
addModJar(fabricApi.module("fabric-resource-loader-v0", rootProject.fabric_api_version))
|
||||||
|
}
|
||||||
|
else // > 1.21.9
|
||||||
|
{
|
||||||
|
addModJar(fabricApi.module("fabric-resource-loader-v0", rootProject.fabric_api_version))
|
||||||
|
addModJar(fabricApi.module("fabric-resource-loader-v1", rootProject.fabric_api_version))
|
||||||
|
}
|
||||||
addModJar(fabricApi.module("fabric-events-interaction-v0", rootProject.fabric_api_version))
|
addModJar(fabricApi.module("fabric-events-interaction-v0", rootProject.fabric_api_version))
|
||||||
addModJar(fabricApi.module("fabric-rendering-v1", rootProject.fabric_api_version)) // TODO: Remove this as it is only needed in 1 line (FabricClientProxy)
|
addModJar(fabricApi.module("fabric-rendering-v1", rootProject.fabric_api_version))
|
||||||
addModJar(fabricApi.module("fabric-networking-api-v1", rootProject.fabric_api_version))
|
addModJar(fabricApi.module("fabric-networking-api-v1", rootProject.fabric_api_version))
|
||||||
addModJar(fabricApi.module("fabric-entity-events-v1", rootProject.fabric_api_version))
|
addModJar(fabricApi.module("fabric-entity-events-v1", rootProject.fabric_api_version))
|
||||||
if (minecraft_version >= "1.19.2")
|
if (buildVersionBefore(minecraft_version, "1.19.2"))
|
||||||
addModJar(fabricApi.module("fabric-command-api-v2", rootProject.fabric_api_version))
|
|
||||||
else // < 1.19.2
|
|
||||||
addModJar(fabricApi.module("fabric-command-api-v1", rootProject.fabric_api_version))
|
addModJar(fabricApi.module("fabric-command-api-v1", rootProject.fabric_api_version))
|
||||||
|
else
|
||||||
|
addModJar(fabricApi.module("fabric-command-api-v2", rootProject.fabric_api_version))
|
||||||
|
|
||||||
// used by mod menu in MC 1.20.6+
|
// used by mod menu in MC 1.20.6+
|
||||||
addModJar(fabricApi.module("fabric-screen-api-v1", rootProject.fabric_api_version))
|
addModJar(fabricApi.module("fabric-screen-api-v1", rootProject.fabric_api_version))
|
||||||
@@ -143,6 +153,40 @@ dependencies {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static boolean buildVersionBefore(String minecraft_version, String compareVersion)
|
||||||
|
{
|
||||||
|
int sortValue = sortSemanticVersionOldestToNewest(minecraft_version, compareVersion);
|
||||||
|
return sortValue == -1;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* input format: "major.minor.patch"
|
||||||
|
* needed so we can sort versions with different length strings
|
||||||
|
* IE: 1.21.1 should come before 1.21.10
|
||||||
|
*/
|
||||||
|
private static int sortSemanticVersionOldestToNewest(String version1, String version2)
|
||||||
|
{
|
||||||
|
String[] parts1 = version1.split("\\.");
|
||||||
|
String[] parts2 = version2.split("\\.");
|
||||||
|
|
||||||
|
int major1 = Integer.parseInt(parts1[0]);
|
||||||
|
int major2 = Integer.parseInt(parts2[0]);
|
||||||
|
if (major1 != major2)
|
||||||
|
{
|
||||||
|
return Integer.compare(major1, major2);
|
||||||
|
}
|
||||||
|
|
||||||
|
int minor1 = Integer.parseInt(parts1[1]);
|
||||||
|
int minor2 = Integer.parseInt(parts2[1]);
|
||||||
|
if (minor1 != minor2)
|
||||||
|
{
|
||||||
|
return Integer.compare(minor1, minor2);
|
||||||
|
}
|
||||||
|
|
||||||
|
int patch1 = Integer.parseInt(parts1[2]);
|
||||||
|
int patch2 = Integer.parseInt(parts2[2]);
|
||||||
|
return Integer.compare(patch1, patch2);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
task deleteResources(type: Delete) {
|
task deleteResources(type: Delete) {
|
||||||
delete file("build/resources/main")
|
delete file("build/resources/main")
|
||||||
|
|||||||
@@ -24,25 +24,24 @@ import com.seibel.distanthorizons.common.AbstractPluginPacketSender;
|
|||||||
import com.seibel.distanthorizons.common.wrappers.McObjectConverter;
|
import com.seibel.distanthorizons.common.wrappers.McObjectConverter;
|
||||||
import com.seibel.distanthorizons.common.wrappers.world.ClientLevelWrapper;
|
import com.seibel.distanthorizons.common.wrappers.world.ClientLevelWrapper;
|
||||||
import com.seibel.distanthorizons.core.api.internal.ClientApi;
|
import com.seibel.distanthorizons.core.api.internal.ClientApi;
|
||||||
import com.mojang.blaze3d.platform.InputConstants;
|
|
||||||
import com.seibel.distanthorizons.common.wrappers.chunk.ChunkWrapper;
|
import com.seibel.distanthorizons.common.wrappers.chunk.ChunkWrapper;
|
||||||
|
|
||||||
import com.seibel.distanthorizons.core.api.internal.SharedApi;
|
import com.seibel.distanthorizons.core.api.internal.SharedApi;
|
||||||
import com.seibel.distanthorizons.core.dependencyInjection.ModAccessorInjector;
|
import com.seibel.distanthorizons.core.dependencyInjection.ModAccessorInjector;
|
||||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||||
|
import com.seibel.distanthorizons.core.util.math.Mat4f;
|
||||||
import com.seibel.distanthorizons.core.util.threading.ThreadPoolUtil;
|
import com.seibel.distanthorizons.core.util.threading.ThreadPoolUtil;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
|
||||||
|
import com.seibel.distanthorizons.core.wrapperInterfaces.misc.IPluginPacketSender;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.ISodiumAccessor;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.ISodiumAccessor;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
|
||||||
import com.seibel.distanthorizons.core.util.math.Mat4f;
|
|
||||||
import com.seibel.distanthorizons.fabric.wrappers.modAccessor.SodiumAccessor;
|
import com.seibel.distanthorizons.fabric.wrappers.modAccessor.SodiumAccessor;
|
||||||
import net.fabricmc.api.EnvType;
|
import net.fabricmc.api.EnvType;
|
||||||
import net.fabricmc.api.Environment;
|
import net.fabricmc.api.Environment;
|
||||||
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientChunkEvents;
|
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientChunkEvents;
|
||||||
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
|
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
|
||||||
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking;
|
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking;
|
||||||
import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderEvents;
|
|
||||||
import net.fabricmc.fabric.api.event.player.AttackBlockCallback;
|
import net.fabricmc.fabric.api.event.player.AttackBlockCallback;
|
||||||
import net.fabricmc.fabric.api.event.player.UseBlockCallback;
|
import net.fabricmc.fabric.api.event.player.UseBlockCallback;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
@@ -60,13 +59,16 @@ import java.nio.FloatBuffer;
|
|||||||
#endif
|
#endif
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.concurrent.AbstractExecutorService;
|
import java.util.concurrent.AbstractExecutorService;
|
||||||
import java.util.concurrent.ThreadPoolExecutor;
|
|
||||||
|
#if MC_VER < MC_1_21_9
|
||||||
|
import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderEvents;
|
||||||
|
#endif
|
||||||
|
|
||||||
import net.minecraft.client.multiplayer.ClientLevel;
|
import net.minecraft.client.multiplayer.ClientLevel;
|
||||||
import net.minecraft.world.InteractionResult;
|
import net.minecraft.world.InteractionResult;
|
||||||
import net.minecraft.world.level.chunk.ChunkAccess;
|
import net.minecraft.world.level.chunk.ChunkAccess;
|
||||||
import net.minecraft.world.phys.HitResult;
|
import net.minecraft.world.phys.HitResult;
|
||||||
import org.apache.logging.log4j.Logger;
|
import com.seibel.distanthorizons.core.logging.DhLogger;
|
||||||
import org.lwjgl.glfw.GLFW;
|
import org.lwjgl.glfw.GLFW;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -82,7 +84,8 @@ public class FabricClientProxy implements AbstractModInitializer.IEventProxy
|
|||||||
{
|
{
|
||||||
private final ClientApi clientApi = ClientApi.INSTANCE;
|
private final ClientApi clientApi = ClientApi.INSTANCE;
|
||||||
private static final IMinecraftClientWrapper MC = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class);
|
private static final IMinecraftClientWrapper MC = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class);
|
||||||
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
|
private static final AbstractPluginPacketSender PACKET_SENDER = (AbstractPluginPacketSender) SingletonInjector.INSTANCE.get(IPluginPacketSender.class);
|
||||||
|
private static final DhLogger LOGGER = new DhLoggerBuilder().build();
|
||||||
|
|
||||||
// TODO we shouldn't be filtering keys on the Forge/Fabric side, only in ClientApi
|
// TODO we shouldn't be filtering keys on the Forge/Fabric side, only in ClientApi
|
||||||
private static final int[] KEY_TO_CHECK_FOR = { GLFW.GLFW_KEY_F6, GLFW.GLFW_KEY_F8, GLFW.GLFW_KEY_P};
|
private static final int[] KEY_TO_CHECK_FOR = { GLFW.GLFW_KEY_F6, GLFW.GLFW_KEY_F8, GLFW.GLFW_KEY_P};
|
||||||
@@ -101,6 +104,7 @@ public class FabricClientProxy implements AbstractModInitializer.IEventProxy
|
|||||||
LOGGER.info("Registering Fabric Client Events");
|
LOGGER.info("Registering Fabric Client Events");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//========================//
|
//========================//
|
||||||
// register mod accessors //
|
// register mod accessors //
|
||||||
//========================//
|
//========================//
|
||||||
@@ -126,8 +130,16 @@ public class FabricClientProxy implements AbstractModInitializer.IEventProxy
|
|||||||
{
|
{
|
||||||
if (MC.clientConnectedToDedicatedServer())
|
if (MC.clientConnectedToDedicatedServer())
|
||||||
{
|
{
|
||||||
IClientLevelWrapper wrappedLevel = ClientLevelWrapper.getWrapper(level);
|
// executor to prevent locking up the render/event thread
|
||||||
SharedApi.INSTANCE.chunkLoadEvent(new ChunkWrapper(chunk, wrappedLevel), wrappedLevel);
|
AbstractExecutorService executor = ThreadPoolUtil.getFileHandlerExecutor();
|
||||||
|
if (executor != null)
|
||||||
|
{
|
||||||
|
executor.execute(() ->
|
||||||
|
{
|
||||||
|
IClientLevelWrapper wrappedLevel = ClientLevelWrapper.getWrapper(level);
|
||||||
|
SharedApi.INSTANCE.chunkLoadEvent(new ChunkWrapper(chunk, wrappedLevel), wrappedLevel);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -141,8 +153,6 @@ public class FabricClientProxy implements AbstractModInitializer.IEventProxy
|
|||||||
if (SharedApi.isChunkAtBlockPosAlreadyUpdating(blockPos.getX(), blockPos.getZ()))
|
if (SharedApi.isChunkAtBlockPosAlreadyUpdating(blockPos.getX(), blockPos.getZ()))
|
||||||
{
|
{
|
||||||
// executor to prevent locking up the render/event thread
|
// executor to prevent locking up the render/event thread
|
||||||
// if the getChunk() takes longer than expected
|
|
||||||
// (which can be caused by certain mods)
|
|
||||||
AbstractExecutorService executor = ThreadPoolUtil.getFileHandlerExecutor();
|
AbstractExecutorService executor = ThreadPoolUtil.getFileHandlerExecutor();
|
||||||
if (executor != null)
|
if (executor != null)
|
||||||
{
|
{
|
||||||
@@ -181,8 +191,6 @@ public class FabricClientProxy implements AbstractModInitializer.IEventProxy
|
|||||||
if (SharedApi.isChunkAtBlockPosAlreadyUpdating(hitResult.getBlockPos().getX(), hitResult.getBlockPos().getZ()))
|
if (SharedApi.isChunkAtBlockPosAlreadyUpdating(hitResult.getBlockPos().getX(), hitResult.getBlockPos().getZ()))
|
||||||
{
|
{
|
||||||
// executor to prevent locking up the render/event thread
|
// executor to prevent locking up the render/event thread
|
||||||
// if the getChunk() takes longer than expected
|
|
||||||
// (which can be caused by certain mods)
|
|
||||||
AbstractExecutorService executor = ThreadPoolUtil.getFileHandlerExecutor();
|
AbstractExecutorService executor = ThreadPoolUtil.getFileHandlerExecutor();
|
||||||
if (executor != null)
|
if (executor != null)
|
||||||
{
|
{
|
||||||
@@ -215,76 +223,83 @@ public class FabricClientProxy implements AbstractModInitializer.IEventProxy
|
|||||||
// render event //
|
// render event //
|
||||||
//==============//
|
//==============//
|
||||||
|
|
||||||
|
// TODO wait for fabric to re-add their rendering API
|
||||||
|
#if MC_VER < MC_1_21_9
|
||||||
WorldRenderEvents.AFTER_SETUP.register((renderContext) ->
|
WorldRenderEvents.AFTER_SETUP.register((renderContext) ->
|
||||||
{
|
{
|
||||||
Mat4f projectionMatrix = McObjectConverter.Convert(renderContext.projectionMatrix());
|
ClientApi.RENDER_STATE.mcProjectionMatrix = McObjectConverter.Convert(renderContext.projectionMatrix());
|
||||||
|
|
||||||
Mat4f modelViewMatrix;
|
|
||||||
#if MC_VER < MC_1_20_6
|
#if MC_VER < MC_1_20_6
|
||||||
modelViewMatrix = McObjectConverter.Convert(renderContext.matrixStack().last().pose());
|
ClientApi.RENDER_STATE.mcModelViewMatrix = McObjectConverter.Convert(renderContext.matrixStack().last().pose());
|
||||||
#else
|
#else
|
||||||
modelViewMatrix = McObjectConverter.Convert(renderContext.positionMatrix());
|
ClientApi.RENDER_STATE.mcModelViewMatrix = McObjectConverter.Convert(renderContext.positionMatrix());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
this.clientApi.renderLods(ClientLevelWrapper.getWrapper(renderContext.world()),
|
#if MC_VER < MC_1_21_1
|
||||||
modelViewMatrix,
|
ClientApi.RENDER_STATE.frameTime = renderContext.tickDelta();
|
||||||
projectionMatrix,
|
#else
|
||||||
#if MC_VER < MC_1_21_1
|
ClientApi.RENDER_STATE.frameTime = renderContext.tickCounter().getGameTimeDeltaTicks();
|
||||||
renderContext.tickDelta()
|
#endif
|
||||||
#else
|
|
||||||
renderContext.tickCounter().getGameTimeDeltaTicks()
|
ClientApi.RENDER_STATE.clientLevelWrapper = ClientLevelWrapper.getWrapperIfDifferent(ClientApi.RENDER_STATE.clientLevelWrapper, renderContext.world());
|
||||||
#endif
|
|
||||||
);
|
|
||||||
|
this.clientApi.renderLods();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
// TODO add to forge and neo
|
|
||||||
WorldRenderEvents.AFTER_ENTITIES.register((renderContext) ->
|
WorldRenderEvents.AFTER_ENTITIES.register((renderContext) ->
|
||||||
{
|
{
|
||||||
Mat4f projectionMatrix = McObjectConverter.Convert(renderContext.projectionMatrix());
|
ClientApi.RENDER_STATE.mcProjectionMatrix = McObjectConverter.Convert(renderContext.projectionMatrix());
|
||||||
|
|
||||||
Mat4f modelViewMatrix;
|
|
||||||
#if MC_VER < MC_1_20_6
|
#if MC_VER < MC_1_20_6
|
||||||
modelViewMatrix = McObjectConverter.Convert(renderContext.matrixStack().last().pose());
|
ClientApi.RENDER_STATE.mcModelViewMatrix = McObjectConverter.Convert(renderContext.matrixStack().last().pose());
|
||||||
#else
|
#else
|
||||||
modelViewMatrix = McObjectConverter.Convert(renderContext.positionMatrix());
|
ClientApi.RENDER_STATE.mcModelViewMatrix = McObjectConverter.Convert(renderContext.positionMatrix());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
this.clientApi.renderFadeOpaque(
|
#if MC_VER < MC_1_21_1
|
||||||
modelViewMatrix,
|
ClientApi.RENDER_STATE.frameTime = renderContext.tickDelta();
|
||||||
projectionMatrix,
|
#else
|
||||||
#if MC_VER < MC_1_21_1
|
ClientApi.RENDER_STATE.frameTime = renderContext.tickCounter().getGameTimeDeltaTicks();
|
||||||
renderContext.tickDelta(),
|
#endif
|
||||||
#else
|
|
||||||
renderContext.tickCounter().getGameTimeDeltaTicks(),
|
ClientApi.RENDER_STATE.clientLevelWrapper = ClientLevelWrapper.getWrapperIfDifferent(ClientApi.RENDER_STATE.clientLevelWrapper, renderContext.world());
|
||||||
#endif
|
|
||||||
ClientLevelWrapper.getWrapper(renderContext.world())
|
|
||||||
);
|
this.clientApi.renderFadeOpaque();
|
||||||
});
|
});
|
||||||
|
|
||||||
// TODO add to forge and neo
|
|
||||||
WorldRenderEvents.AFTER_TRANSLUCENT.register((renderContext) ->
|
WorldRenderEvents.AFTER_TRANSLUCENT.register((renderContext) ->
|
||||||
{
|
{
|
||||||
Mat4f projectionMatrix = McObjectConverter.Convert(renderContext.projectionMatrix());
|
ClientApi.RENDER_STATE.mcProjectionMatrix = McObjectConverter.Convert(renderContext.projectionMatrix());
|
||||||
|
|
||||||
Mat4f modelViewMatrix;
|
|
||||||
#if MC_VER < MC_1_20_6
|
#if MC_VER < MC_1_20_6
|
||||||
modelViewMatrix = McObjectConverter.Convert(renderContext.matrixStack().last().pose());
|
ClientApi.RENDER_STATE.mcModelViewMatrix = McObjectConverter.Convert(renderContext.matrixStack().last().pose());
|
||||||
#else
|
#else
|
||||||
modelViewMatrix = McObjectConverter.Convert(renderContext.positionMatrix());
|
ClientApi.RENDER_STATE.mcModelViewMatrix = McObjectConverter.Convert(renderContext.positionMatrix());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
this.clientApi.renderFade(
|
#if MC_VER < MC_1_21_1
|
||||||
modelViewMatrix,
|
ClientApi.RENDER_STATE.frameTime = renderContext.tickDelta();
|
||||||
projectionMatrix,
|
#else
|
||||||
#if MC_VER < MC_1_21_1
|
ClientApi.RENDER_STATE.frameTime = renderContext.tickCounter().getGameTimeDeltaTicks();
|
||||||
renderContext.tickDelta(),
|
#endif
|
||||||
#else
|
|
||||||
renderContext.tickCounter().getGameTimeDeltaTicks(),
|
ClientApi.RENDER_STATE.clientLevelWrapper = ClientLevelWrapper.getWrapperIfDifferent(ClientApi.RENDER_STATE.clientLevelWrapper, renderContext.world());
|
||||||
#endif
|
|
||||||
ClientLevelWrapper.getWrapper(renderContext.world())
|
|
||||||
);
|
|
||||||
|
|
||||||
|
#if MC_VER < MC_1_21_6
|
||||||
|
// rendered in MixinLevelRenderer
|
||||||
|
#else
|
||||||
|
ClientApi.INSTANCE.renderDeferredLodsForShaders();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
this.clientApi.renderFadeTransparent();
|
||||||
});
|
});
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
// Debug keyboard event
|
// Debug keyboard event
|
||||||
@@ -316,9 +331,7 @@ public class FabricClientProxy implements AbstractModInitializer.IEventProxy
|
|||||||
#else
|
#else
|
||||||
ClientPlayNetworking.registerGlobalReceiver(AbstractPluginPacketSender.WRAPPER_PACKET_RESOURCE, (client, handler, buffer, packetSender) ->
|
ClientPlayNetworking.registerGlobalReceiver(AbstractPluginPacketSender.WRAPPER_PACKET_RESOURCE, (client, handler, buffer, packetSender) ->
|
||||||
{
|
{
|
||||||
// Forge packet ID
|
AbstractNetworkMessage message = PACKET_SENDER.decodeMessage(buffer);
|
||||||
buffer.readByte();
|
|
||||||
AbstractNetworkMessage message = AbstractPluginPacketSender.decodeMessage(buffer);
|
|
||||||
if (message != null)
|
if (message != null)
|
||||||
{
|
{
|
||||||
ClientApi.INSTANCE.pluginMessageReceived(message);
|
ClientApi.INSTANCE.pluginMessageReceived(message);
|
||||||
@@ -336,18 +349,18 @@ public class FabricClientProxy implements AbstractModInitializer.IEventProxy
|
|||||||
// Check all keys we need
|
// Check all keys we need
|
||||||
for (int keyCode = GLFW.GLFW_KEY_A; keyCode <= GLFW.GLFW_KEY_Z; keyCode++)
|
for (int keyCode = GLFW.GLFW_KEY_A; keyCode <= GLFW.GLFW_KEY_Z; keyCode++)
|
||||||
{
|
{
|
||||||
if (InputConstants.isKeyDown(Minecraft.getInstance().getWindow().getWindow(), keyCode))
|
//if (InputConstants.isKeyDown(Minecraft.getInstance().getWindow().getWindow(), keyCode))
|
||||||
{
|
//{
|
||||||
currentKeyDown.add(keyCode);
|
// currentKeyDown.add(keyCode);
|
||||||
}
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int keyCode : KEY_TO_CHECK_FOR)
|
for (int keyCode : KEY_TO_CHECK_FOR)
|
||||||
{
|
{
|
||||||
if (InputConstants.isKeyDown(Minecraft.getInstance().getWindow().getWindow(), keyCode))
|
//if (InputConstants.isKeyDown(Minecraft.getInstance().getWindow().getWindow(), keyCode))
|
||||||
{
|
//{
|
||||||
currentKeyDown.add(keyCode);
|
// currentKeyDown.add(keyCode);
|
||||||
}
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Diff and trigger events
|
// Diff and trigger events
|
||||||
|
|||||||
@@ -22,7 +22,6 @@ package com.seibel.distanthorizons.fabric;
|
|||||||
import com.mojang.brigadier.CommandDispatcher;
|
import com.mojang.brigadier.CommandDispatcher;
|
||||||
import com.seibel.distanthorizons.common.AbstractModInitializer;
|
import com.seibel.distanthorizons.common.AbstractModInitializer;
|
||||||
import com.seibel.distanthorizons.core.config.Config;
|
import com.seibel.distanthorizons.core.config.Config;
|
||||||
import com.seibel.distanthorizons.core.config.ConfigBase;
|
|
||||||
import com.seibel.distanthorizons.core.dependencyInjection.ModAccessorInjector;
|
import com.seibel.distanthorizons.core.dependencyInjection.ModAccessorInjector;
|
||||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||||
@@ -39,7 +38,7 @@ import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents;
|
|||||||
import net.minecraft.commands.CommandSourceStack;
|
import net.minecraft.commands.CommandSourceStack;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
import net.minecraft.server.MinecraftServer;
|
import net.minecraft.server.MinecraftServer;
|
||||||
import org.apache.logging.log4j.Logger;
|
import com.seibel.distanthorizons.core.logging.DhLogger;
|
||||||
import org.lwjgl.util.tinyfd.TinyFileDialogs;
|
import org.lwjgl.util.tinyfd.TinyFileDialogs;
|
||||||
|
|
||||||
#if MC_VER >= MC_1_19_2
|
#if MC_VER >= MC_1_19_2
|
||||||
@@ -65,16 +64,19 @@ public class FabricMain extends AbstractModInitializer implements ClientModIniti
|
|||||||
private static final ResourceLocation INITIAL_PHASE = new ResourceLocation(ModInfo.RESOURCE_NAMESPACE, ModInfo.DEDICATED_SERVER_INITIAL_PATH);
|
private static final ResourceLocation INITIAL_PHASE = new ResourceLocation(ModInfo.RESOURCE_NAMESPACE, ModInfo.DEDICATED_SERVER_INITIAL_PATH);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
|
private static final DhLogger LOGGER = new DhLoggerBuilder().build();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void createInitialBindings()
|
protected void createInitialSharedBindings()
|
||||||
{
|
{
|
||||||
SingletonInjector.INSTANCE.bind(IModChecker.class, ModChecker.INSTANCE);
|
SingletonInjector.INSTANCE.bind(IModChecker.class, ModChecker.INSTANCE);
|
||||||
SingletonInjector.INSTANCE.bind(IPluginPacketSender.class, new FabricPluginPacketSender());
|
SingletonInjector.INSTANCE.bind(IPluginPacketSender.class, new FabricPluginPacketSender());
|
||||||
}
|
}
|
||||||
|
@Override
|
||||||
|
protected void createInitialClientBindings() { /* no additional setup needed currently */ }
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected IEventProxy createClientProxy() { return new FabricClientProxy(); }
|
protected IEventProxy createClientProxy() { return new FabricClientProxy(); }
|
||||||
@@ -90,8 +92,8 @@ public class FabricMain extends AbstractModInitializer implements ClientModIniti
|
|||||||
{
|
{
|
||||||
ModAccessorInjector.INSTANCE.bind(ISodiumAccessor.class, new SodiumAccessor());
|
ModAccessorInjector.INSTANCE.bind(ISodiumAccessor.class, new SodiumAccessor());
|
||||||
|
|
||||||
// If sodium is installed Indium is also necessary in order to use the Fabric rendering API
|
// If sodium is installed Indium is also necessary for versions 0.5 and less in order to use the Fabric rendering API
|
||||||
if (!modChecker.isModLoaded("indium"))
|
if (!modChecker.isModLoaded("indium") && SodiumAccessor.isSodiumV5OrLess)
|
||||||
{
|
{
|
||||||
String indiumMissingMessage = ModInfo.READABLE_NAME + " needs Indium to work with Sodium.\nPlease download Indium from https://modrinth.com/mod/indium";
|
String indiumMissingMessage = ModInfo.READABLE_NAME + " needs Indium to work with Sodium.\nPlease download Indium from https://modrinth.com/mod/indium";
|
||||||
LOGGER.fatal(indiumMissingMessage);
|
LOGGER.fatal(indiumMissingMessage);
|
||||||
@@ -126,7 +128,8 @@ public class FabricMain extends AbstractModInitializer implements ClientModIniti
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void subscribeClientStartedEvent(Runnable eventHandler) { ClientLifecycleEvents.CLIENT_STARTED.register((mc) -> eventHandler.run()); }
|
protected void subscribeClientStartedEvent(Runnable eventHandler)
|
||||||
|
{ ClientLifecycleEvents.CLIENT_STARTED.register((mc) -> eventHandler.run()); }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void subscribeServerStartingEvent(Consumer<MinecraftServer> eventHandler)
|
protected void subscribeServerStartingEvent(Consumer<MinecraftServer> eventHandler)
|
||||||
@@ -151,11 +154,6 @@ public class FabricMain extends AbstractModInitializer implements ClientModIniti
|
|||||||
ModAccessorInjector.INSTANCE.get(ISodiumAccessor.class).setFogOcclusion(false);
|
ModAccessorInjector.INSTANCE.get(ISodiumAccessor.class).setFogOcclusion(false);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (ConfigBase.INSTANCE == null)
|
|
||||||
{
|
|
||||||
throw new IllegalStateException("Config was not initialized. Make sure to call LodCommonMain.initConfig() before calling this method.");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-6
@@ -22,9 +22,7 @@ public class FabricPluginPacketSender extends AbstractPluginPacketSender
|
|||||||
ClientPlayNetworking.send(new CommonPacketPayload(message));
|
ClientPlayNetworking.send(new CommonPacketPayload(message));
|
||||||
#else // < 1.20.6
|
#else // < 1.20.6
|
||||||
FriendlyByteBuf buffer = PacketByteBufs.create();
|
FriendlyByteBuf buffer = PacketByteBufs.create();
|
||||||
// Forge packet ID
|
this.encodeMessage(buffer, message);
|
||||||
buffer.writeByte(0);
|
|
||||||
AbstractPluginPacketSender.encodeMessage(buffer, message);
|
|
||||||
ClientPlayNetworking.send(WRAPPER_PACKET_RESOURCE, buffer);
|
ClientPlayNetworking.send(WRAPPER_PACKET_RESOURCE, buffer);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -36,9 +34,7 @@ public class FabricPluginPacketSender extends AbstractPluginPacketSender
|
|||||||
ServerPlayNetworking.send(serverPlayer, new CommonPacketPayload(message));
|
ServerPlayNetworking.send(serverPlayer, new CommonPacketPayload(message));
|
||||||
#else // < 1.20.6
|
#else // < 1.20.6
|
||||||
FriendlyByteBuf buffer = PacketByteBufs.create();
|
FriendlyByteBuf buffer = PacketByteBufs.create();
|
||||||
// Forge packet ID
|
this.encodeMessage(buffer, message);
|
||||||
buffer.writeByte(0);
|
|
||||||
AbstractPluginPacketSender.encodeMessage(buffer, message);
|
|
||||||
ServerPlayNetworking.send(serverPlayer, WRAPPER_PACKET_RESOURCE, buffer);
|
ServerPlayNetworking.send(serverPlayer, WRAPPER_PACKET_RESOURCE, buffer);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
package com.seibel.distanthorizons.fabric;
|
package com.seibel.distanthorizons.fabric;
|
||||||
|
|
||||||
|
import com.seibel.distanthorizons.api.DhApi;
|
||||||
|
import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiChunkProcessingEvent;
|
||||||
import com.seibel.distanthorizons.api.methods.events.DhApiEventRegister;
|
import com.seibel.distanthorizons.api.methods.events.DhApiEventRegister;
|
||||||
import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiLevelLoadEvent;
|
import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiLevelLoadEvent;
|
||||||
import com.seibel.distanthorizons.common.AbstractModInitializer;
|
import com.seibel.distanthorizons.common.AbstractModInitializer;
|
||||||
@@ -7,11 +9,14 @@ import com.seibel.distanthorizons.common.wrappers.chunk.ChunkWrapper;
|
|||||||
import com.seibel.distanthorizons.common.wrappers.misc.ServerPlayerWrapper;
|
import com.seibel.distanthorizons.common.wrappers.misc.ServerPlayerWrapper;
|
||||||
import com.seibel.distanthorizons.common.wrappers.world.ClientLevelWrapper;
|
import com.seibel.distanthorizons.common.wrappers.world.ClientLevelWrapper;
|
||||||
import com.seibel.distanthorizons.common.wrappers.world.ServerLevelWrapper;
|
import com.seibel.distanthorizons.common.wrappers.world.ServerLevelWrapper;
|
||||||
import com.seibel.distanthorizons.common.wrappers.worldGeneration.BatchGenerationEnvironment;
|
|
||||||
import com.seibel.distanthorizons.core.api.internal.ServerApi;
|
import com.seibel.distanthorizons.core.api.internal.ServerApi;
|
||||||
|
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||||
|
import com.seibel.distanthorizons.common.AbstractPluginPacketSender;
|
||||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||||
|
import com.seibel.distanthorizons.core.wrapperInterfaces.misc.IPluginPacketSender;
|
||||||
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.TestChunkInputReplacerEvent;
|
||||||
import com.seibel.distanthorizons.fabric.testing.TestWorldGenBindingEvent;
|
import com.seibel.distanthorizons.fabric.testing.TestWorldGenBindingEvent;
|
||||||
import net.fabricmc.fabric.api.entity.event.v1.ServerEntityWorldChangeEvents;
|
import net.fabricmc.fabric.api.entity.event.v1.ServerEntityWorldChangeEvents;
|
||||||
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerChunkEvents;
|
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerChunkEvents;
|
||||||
@@ -25,18 +30,15 @@ import net.minecraft.client.gui.screens.TitleScreen;
|
|||||||
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.server.level.ServerPlayer;
|
import net.minecraft.server.level.ServerPlayer;
|
||||||
import org.apache.logging.log4j.Logger;
|
import com.seibel.distanthorizons.core.logging.DhLogger;
|
||||||
|
|
||||||
#if MC_VER >= MC_1_20_6
|
#if MC_VER >= MC_1_20_6
|
||||||
import com.seibel.distanthorizons.common.CommonPacketPayload;
|
import com.seibel.distanthorizons.common.CommonPacketPayload;
|
||||||
import net.fabricmc.fabric.api.networking.v1.PayloadTypeRegistry;
|
import net.fabricmc.fabric.api.networking.v1.PayloadTypeRegistry;
|
||||||
#else
|
#else
|
||||||
import com.seibel.distanthorizons.core.network.messages.AbstractNetworkMessage;
|
import com.seibel.distanthorizons.core.network.messages.AbstractNetworkMessage;
|
||||||
import com.seibel.distanthorizons.common.AbstractPluginPacketSender;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
import java.util.function.Supplier;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This handles all events sent to the server,
|
* This handles all events sent to the server,
|
||||||
* and is the starting point for most of the mod.
|
* and is the starting point for most of the mod.
|
||||||
@@ -48,7 +50,9 @@ import java.util.function.Supplier;
|
|||||||
public class FabricServerProxy implements AbstractModInitializer.IEventProxy
|
public class FabricServerProxy implements AbstractModInitializer.IEventProxy
|
||||||
{
|
{
|
||||||
private static final ServerApi SERVER_API = ServerApi.INSTANCE;
|
private static final ServerApi SERVER_API = ServerApi.INSTANCE;
|
||||||
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
|
@SuppressWarnings("unused")
|
||||||
|
private static final AbstractPluginPacketSender PACKET_SENDER = (AbstractPluginPacketSender) SingletonInjector.INSTANCE.get(IPluginPacketSender.class);
|
||||||
|
private static final DhLogger LOGGER = new DhLoggerBuilder().build();
|
||||||
|
|
||||||
private final boolean isDedicatedServer;
|
private final boolean isDedicatedServer;
|
||||||
|
|
||||||
@@ -93,10 +97,11 @@ public class FabricServerProxy implements AbstractModInitializer.IEventProxy
|
|||||||
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
|
// can be enabled to test overrides/events without having to build a separate API project
|
||||||
if (false)
|
if (false)
|
||||||
{
|
{
|
||||||
DhApiEventRegister.on(DhApiLevelLoadEvent.class, new TestWorldGenBindingEvent());
|
DhApiEventRegister.on(DhApiLevelLoadEvent.class, new TestWorldGenBindingEvent());
|
||||||
|
DhApi.events.bind(DhApiChunkProcessingEvent.class, new TestChunkInputReplacerEvent());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -192,9 +197,7 @@ public class FabricServerProxy implements AbstractModInitializer.IEventProxy
|
|||||||
#else
|
#else
|
||||||
ServerPlayNetworking.registerGlobalReceiver(AbstractPluginPacketSender.WRAPPER_PACKET_RESOURCE, (server, serverPlayer, handler, buffer, packetSender) ->
|
ServerPlayNetworking.registerGlobalReceiver(AbstractPluginPacketSender.WRAPPER_PACKET_RESOURCE, (server, serverPlayer, handler, buffer, packetSender) ->
|
||||||
{
|
{
|
||||||
// Forge packet ID
|
AbstractNetworkMessage message = PACKET_SENDER.decodeMessage(buffer);
|
||||||
buffer.readByte();
|
|
||||||
AbstractNetworkMessage message = AbstractPluginPacketSender.decodeMessage(buffer);
|
|
||||||
if (message != null)
|
if (message != null)
|
||||||
{
|
{
|
||||||
ServerApi.INSTANCE.pluginMessageReceived(ServerPlayerWrapper.getWrapper(serverPlayer), message);
|
ServerApi.INSTANCE.pluginMessageReceived(ServerPlayerWrapper.getWrapper(serverPlayer), message);
|
||||||
|
|||||||
+70
@@ -0,0 +1,70 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the Distant Horizons mod
|
||||||
|
* licensed under the GNU LGPL v3 License.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2020 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.fabric.mixins.client;
|
||||||
|
|
||||||
|
#if MC_VER < MC_1_21_9
|
||||||
|
import net.minecraft.world.entity.Entity;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
|
||||||
|
@Mixin(Entity.class)
|
||||||
|
public class MixinChunkSectionsToRender
|
||||||
|
{ /* rendering before was handled via Fabric API events */ }
|
||||||
|
#else
|
||||||
|
|
||||||
|
import com.seibel.distanthorizons.common.wrappers.world.ClientLevelWrapper;
|
||||||
|
import com.seibel.distanthorizons.core.api.internal.ClientApi;
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.client.renderer.chunk.ChunkSectionLayerGroup;
|
||||||
|
import net.minecraft.client.renderer.chunk.ChunkSectionsToRender;
|
||||||
|
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;
|
||||||
|
|
||||||
|
@Mixin(ChunkSectionsToRender.class)
|
||||||
|
public class MixinChunkSectionsToRender
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
// needs to fire at HEAD with a lower than normal order (less than 1000)
|
||||||
|
// otherwise it will be canceled by Sodium
|
||||||
|
@Inject(at = @At("HEAD"), method = "renderGroup", order = 800)
|
||||||
|
private void renderDeferredLayer(ChunkSectionLayerGroup chunkSectionLayerGroup, CallbackInfo ci)
|
||||||
|
{
|
||||||
|
ClientApi.RENDER_STATE.clientLevelWrapper = ClientLevelWrapper.getWrapperIfDifferent(ClientApi.RENDER_STATE.clientLevelWrapper, Minecraft.getInstance().levelRenderer.level);
|
||||||
|
|
||||||
|
|
||||||
|
if (chunkSectionLayerGroup == ChunkSectionLayerGroup.TRANSLUCENT)
|
||||||
|
{
|
||||||
|
ClientApi.INSTANCE.renderFadeTransparent();
|
||||||
|
ClientApi.INSTANCE.renderDeferredLodsForShaders();
|
||||||
|
}
|
||||||
|
else if (chunkSectionLayerGroup == ChunkSectionLayerGroup.TRIPWIRE)
|
||||||
|
{
|
||||||
|
ClientApi.INSTANCE.renderFadeOpaque();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
+22
-2
@@ -3,8 +3,10 @@ package com.seibel.distanthorizons.fabric.mixins.client;
|
|||||||
import com.seibel.distanthorizons.common.wrappers.world.ClientLevelWrapper;
|
import com.seibel.distanthorizons.common.wrappers.world.ClientLevelWrapper;
|
||||||
import com.seibel.distanthorizons.core.api.internal.ClientApi;
|
import com.seibel.distanthorizons.core.api.internal.ClientApi;
|
||||||
import com.seibel.distanthorizons.core.api.internal.SharedApi;
|
import com.seibel.distanthorizons.core.api.internal.SharedApi;
|
||||||
|
import com.seibel.distanthorizons.core.util.threading.ThreadPoolUtil;
|
||||||
import net.minecraft.client.multiplayer.ClientLevel;
|
import net.minecraft.client.multiplayer.ClientLevel;
|
||||||
import net.minecraft.client.multiplayer.ClientPacketListener;
|
import net.minecraft.client.multiplayer.ClientPacketListener;
|
||||||
|
import net.minecraft.world.level.chunk.ChunkAccess;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
import org.spongepowered.asm.mixin.Unique;
|
import org.spongepowered.asm.mixin.Unique;
|
||||||
@@ -16,6 +18,8 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
|||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
|
||||||
import net.minecraft.world.level.chunk.LevelChunk;
|
import net.minecraft.world.level.chunk.LevelChunk;
|
||||||
import com.seibel.distanthorizons.common.wrappers.chunk.ChunkWrapper;
|
import com.seibel.distanthorizons.common.wrappers.chunk.ChunkWrapper;
|
||||||
|
|
||||||
|
import java.util.concurrent.AbstractExecutorService;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@Mixin(ClientPacketListener.class)
|
@Mixin(ClientPacketListener.class)
|
||||||
@@ -45,8 +49,24 @@ public class MixinClientPacketListener
|
|||||||
@Inject(method = "enableChunkLight", at = @At("TAIL"))
|
@Inject(method = "enableChunkLight", at = @At("TAIL"))
|
||||||
void onEnableChunkLight(LevelChunk chunk, int x, int z, CallbackInfo ci)
|
void onEnableChunkLight(LevelChunk chunk, int x, int z, CallbackInfo ci)
|
||||||
{
|
{
|
||||||
IClientLevelWrapper clientLevel = ClientLevelWrapper.getWrapper((ClientLevel) chunk.getLevel());
|
if (chunk == null)
|
||||||
SharedApi.INSTANCE.chunkLoadEvent(new ChunkWrapper(chunk, clientLevel), clientLevel);
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// executor to prevent locking up the render thread
|
||||||
|
AbstractExecutorService executor = ThreadPoolUtil.getFileHandlerExecutor();
|
||||||
|
if (executor == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
executor.execute(() ->
|
||||||
|
{
|
||||||
|
IClientLevelWrapper clientLevel = ClientLevelWrapper.getWrapper((ClientLevel) this.level);
|
||||||
|
SharedApi.INSTANCE.chunkLoadEvent(new ChunkWrapper(chunk, clientLevel), clientLevel);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+4
-1
@@ -12,12 +12,15 @@ import java.util.List;
|
|||||||
@Mixin(DebugScreenOverlay.class)
|
@Mixin(DebugScreenOverlay.class)
|
||||||
public class MixinDebugScreenOverlay
|
public class MixinDebugScreenOverlay
|
||||||
{
|
{
|
||||||
|
#if MC_VER < MC_1_21_9
|
||||||
@Inject(method = "getSystemInformation", at = @At("RETURN"))
|
@Inject(method = "getSystemInformation", at = @At("RETURN"))
|
||||||
private void addCustomF3(CallbackInfoReturnable<List<String>> cir)
|
private void addCustomF3(CallbackInfoReturnable<List<String>> cir)
|
||||||
{
|
{
|
||||||
List<String> messages = cir.getReturnValue();
|
List<String> messages = cir.getReturnValue();
|
||||||
F3Screen.addStringToDisplay(messages);
|
F3Screen.addStringToDisplay(messages);
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
// handled by DhDebugScreenEntry for MC versions after 1.21.10
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+106
-15
@@ -22,31 +22,51 @@ package com.seibel.distanthorizons.fabric.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;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.Unique;
|
import org.spongepowered.asm.mixin.Unique;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
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.Camera;
|
||||||
import net.minecraft.client.renderer.FogRenderer;
|
|
||||||
import net.minecraft.client.renderer.FogRenderer.FogMode;
|
|
||||||
import net.minecraft.world.effect.MobEffects;
|
import net.minecraft.world.effect.MobEffects;
|
||||||
import net.minecraft.world.entity.Entity;
|
import net.minecraft.world.entity.Entity;
|
||||||
import net.minecraft.world.entity.LivingEntity;
|
import net.minecraft.world.entity.LivingEntity;
|
||||||
|
|
||||||
#if MC_VER < MC_1_17_1
|
#if MC_VER < MC_1_17_1
|
||||||
import net.minecraft.world.level.material.FluidState;
|
import net.minecraft.world.level.material.FluidState;
|
||||||
|
import net.minecraft.client.renderer.FogRenderer;
|
||||||
|
import net.minecraft.client.renderer.FogRenderer.FogMode;
|
||||||
|
import com.mojang.blaze3d.systems.RenderSystem;
|
||||||
|
|
||||||
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
#elif MC_VER < MC_1_21_3
|
#elif MC_VER < MC_1_21_3
|
||||||
import net.minecraft.world.level.material.FogType;
|
import net.minecraft.world.level.material.FogType;
|
||||||
#else
|
import net.minecraft.client.renderer.FogRenderer;
|
||||||
|
import net.minecraft.client.renderer.FogRenderer.FogMode;
|
||||||
|
import com.mojang.blaze3d.systems.RenderSystem;
|
||||||
|
|
||||||
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
#elif MC_VER < MC_1_21_6
|
||||||
import net.minecraft.world.level.material.FogType;
|
import net.minecraft.world.level.material.FogType;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||||
import com.mojang.blaze3d.shaders.FogShape;
|
import com.mojang.blaze3d.shaders.FogShape;
|
||||||
|
import net.minecraft.client.renderer.FogRenderer;
|
||||||
|
import net.minecraft.client.renderer.FogRenderer.FogMode;
|
||||||
import net.minecraft.client.renderer.FogParameters;
|
import net.minecraft.client.renderer.FogParameters;
|
||||||
import org.joml.Vector4f;
|
import org.joml.Vector4f;
|
||||||
|
import com.mojang.blaze3d.systems.RenderSystem;
|
||||||
|
|
||||||
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
#else
|
||||||
|
import net.minecraft.world.level.material.FogType;
|
||||||
|
import net.minecraft.client.renderer.fog.FogRenderer;
|
||||||
|
import net.minecraft.client.renderer.fog.FogData;
|
||||||
|
|
||||||
|
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
|
||||||
|
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@Mixin(FogRenderer.class)
|
@Mixin(FogRenderer.class)
|
||||||
@@ -66,18 +86,23 @@ public class MixinFogRenderer
|
|||||||
#elif MC_VER < MC_1_21_3
|
#elif MC_VER < MC_1_21_3
|
||||||
@Inject(at = @At("RETURN"), method = "setupFog")
|
@Inject(at = @At("RETURN"), method = "setupFog")
|
||||||
private static void disableSetupFog(Camera camera, FogMode fogMode, float f, boolean bl, float g, CallbackInfo callback)
|
private static void disableSetupFog(Camera camera, FogMode fogMode, float f, boolean bl, float g, CallbackInfo callback)
|
||||||
#else
|
#elif MC_VER < MC_1_21_6
|
||||||
@Inject(at = @At("RETURN"), method = "setupFog", cancellable = true)
|
@Inject(at = @At("RETURN"), method = "setupFog", cancellable = true)
|
||||||
private static void disableSetupFog(Camera camera, FogMode fogMode, Vector4f vector4f, float f, boolean bl, float g, CallbackInfoReturnable<FogParameters> callback)
|
private static void disableSetupFog(Camera camera, FogMode fogMode, Vector4f vector4f, float f, boolean bl, float g, CallbackInfoReturnable<FogParameters> callback)
|
||||||
|
#else
|
||||||
|
@Unique
|
||||||
|
private static void unused()
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
boolean cameraNotInFluid = cameraNotInFluid(camera);
|
#if MC_VER < MC_1_21_6
|
||||||
|
boolean cancelFog = cancelFog(camera, fogMode);
|
||||||
|
#elif MC_VER < MC_1_21_6
|
||||||
|
boolean cancelFog = cancelFog(camera);
|
||||||
|
#else
|
||||||
|
boolean cancelFog = cancelFog();
|
||||||
|
#endif
|
||||||
|
|
||||||
Entity entity = camera.getEntity();
|
if (cancelFog)
|
||||||
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.enableVanillaFog.get())
|
|
||||||
{
|
{
|
||||||
#if MC_VER < MC_1_17_1
|
#if MC_VER < MC_1_17_1
|
||||||
RenderSystem.fogStart(A_REALLY_REALLY_BIG_VALUE);
|
RenderSystem.fogStart(A_REALLY_REALLY_BIG_VALUE);
|
||||||
@@ -85,10 +110,74 @@ public class MixinFogRenderer
|
|||||||
#elif MC_VER < MC_1_21_3
|
#elif MC_VER < MC_1_21_3
|
||||||
RenderSystem.setShaderFogStart(A_REALLY_REALLY_BIG_VALUE);
|
RenderSystem.setShaderFogStart(A_REALLY_REALLY_BIG_VALUE);
|
||||||
RenderSystem.setShaderFogEnd(A_EVEN_LARGER_VALUE);
|
RenderSystem.setShaderFogEnd(A_EVEN_LARGER_VALUE);
|
||||||
#else
|
#elif MC_VER < MC_1_21_6
|
||||||
callback.setReturnValue(FogParameters.NO_FOG);
|
callback.setReturnValue(FogParameters.NO_FOG);
|
||||||
|
#else
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if MC_VER < MC_1_21_6
|
||||||
|
#else
|
||||||
|
|
||||||
|
// In MC's FogRenderer they clamp the "renderDistanceEnd" fog field to the render distance,
|
||||||
|
// which prevents us from disabling the vanilla fog.
|
||||||
|
// This mixin fires after they set the "renderDistanceEnd" so we can change it.
|
||||||
|
@WrapOperation(
|
||||||
|
method = "setupFog",
|
||||||
|
at = @At(
|
||||||
|
value = "FIELD",
|
||||||
|
target = "Lnet/minecraft/client/renderer/fog/FogData;renderDistanceEnd:F",
|
||||||
|
opcode = org.objectweb.asm.Opcodes.PUTFIELD
|
||||||
|
)
|
||||||
|
)
|
||||||
|
private void onSetRenderDistanceEnd(FogData instance, float value, Operation<Void> original)
|
||||||
|
{
|
||||||
|
if (cancelFog())
|
||||||
|
{
|
||||||
|
instance.environmentalStart = A_REALLY_REALLY_BIG_VALUE;
|
||||||
|
instance.environmentalEnd = A_EVEN_LARGER_VALUE;
|
||||||
|
|
||||||
|
instance.renderDistanceStart = A_REALLY_REALLY_BIG_VALUE;
|
||||||
|
instance.renderDistanceEnd = A_EVEN_LARGER_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Always call the original with the modified or original value
|
||||||
|
original.call(instance, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
@Unique
|
||||||
|
#if MC_VER < MC_1_21_6
|
||||||
|
private static boolean cancelFog(Camera camera, FogMode fogMode)
|
||||||
|
#else
|
||||||
|
private static boolean cancelFog()
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
#if MC_VER < MC_1_21_6
|
||||||
|
Entity entity = camera.getEntity();
|
||||||
|
#else
|
||||||
|
Camera camera = Minecraft.getInstance().gameRenderer.getMainCamera();
|
||||||
|
Entity entity = camera.getEntity();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
boolean cameraNotInFluid = cameraNotInFluid(camera);
|
||||||
|
boolean isSpecialFog = (entity instanceof LivingEntity) && ((LivingEntity) entity).hasEffect(MobEffects.BLINDNESS);
|
||||||
|
|
||||||
|
boolean cancelFog = !isSpecialFog;
|
||||||
|
cancelFog = cancelFog && cameraNotInFluid;
|
||||||
|
#if MC_VER < MC_1_21_6
|
||||||
|
cancelFog = cancelFog && (fogMode == FogMode.FOG_TERRAIN);
|
||||||
|
#endif
|
||||||
|
cancelFog = cancelFog && !SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class).isFogStateSpecial();
|
||||||
|
cancelFog = cancelFog && !Config.Client.Advanced.Graphics.Fog.enableVanillaFog.get();
|
||||||
|
|
||||||
|
return cancelFog;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Unique
|
@Unique
|
||||||
@@ -105,4 +194,6 @@ public class MixinFogRenderer
|
|||||||
return cameraNotInFluid;
|
return cameraNotInFluid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+112
-48
@@ -19,51 +19,78 @@
|
|||||||
|
|
||||||
package com.seibel.distanthorizons.fabric.mixins.client;
|
package com.seibel.distanthorizons.fabric.mixins.client;
|
||||||
|
|
||||||
import com.mojang.blaze3d.vertex.PoseStack;
|
|
||||||
#if MC_VER < MC_1_19_4
|
#if MC_VER < MC_1_19_4
|
||||||
|
import net.minecraft.client.renderer.RenderType;
|
||||||
|
import com.mojang.blaze3d.vertex.PoseStack;
|
||||||
import com.mojang.math.Matrix4f;
|
import com.mojang.math.Matrix4f;
|
||||||
import org.lwjgl.opengl.GL32;
|
import org.lwjgl.opengl.GL32;
|
||||||
#else
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
#elif MC_VER < MC_1_21_6
|
||||||
|
import net.minecraft.client.renderer.RenderType;
|
||||||
|
import com.mojang.blaze3d.vertex.PoseStack;
|
||||||
import org.joml.Matrix4f;
|
import org.joml.Matrix4f;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
#elif MC_VER < MC_1_21_9
|
||||||
|
import com.mojang.blaze3d.buffers.GpuBufferSlice;
|
||||||
|
import com.mojang.blaze3d.framegraph.FrameGraphBuilder;
|
||||||
|
import com.mojang.blaze3d.resource.GraphicsResourceAllocator;
|
||||||
|
import net.minecraft.client.Camera;
|
||||||
|
import net.minecraft.client.DeltaTracker;
|
||||||
|
import net.minecraft.client.renderer.chunk.ChunkSectionsToRender;
|
||||||
|
import net.minecraft.client.renderer.culling.Frustum;
|
||||||
|
import net.minecraft.util.profiling.ProfilerFiller;
|
||||||
|
import org.joml.Matrix4f;
|
||||||
|
import org.joml.Matrix4fc;
|
||||||
|
import org.joml.Vector4f;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||||
|
#else
|
||||||
|
import com.mojang.blaze3d.buffers.GpuBufferSlice;
|
||||||
|
import com.mojang.blaze3d.framegraph.FrameGraphBuilder;
|
||||||
|
import com.mojang.blaze3d.resource.GraphicsResourceAllocator;
|
||||||
|
import net.minecraft.client.Camera;
|
||||||
|
import net.minecraft.client.DeltaTracker;
|
||||||
|
import net.minecraft.client.renderer.chunk.ChunkSectionsToRender;
|
||||||
|
import net.minecraft.client.renderer.culling.Frustum;
|
||||||
|
import net.minecraft.client.renderer.state.LevelRenderState;
|
||||||
|
import net.minecraft.util.profiling.ProfilerFiller;
|
||||||
|
import org.joml.Matrix4f;
|
||||||
|
import org.joml.Matrix4fc;
|
||||||
|
import org.joml.Vector4f;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||||
#endif
|
#endif
|
||||||
import com.seibel.distanthorizons.common.wrappers.chunk.ChunkWrapper;
|
|
||||||
|
|
||||||
import com.seibel.distanthorizons.common.wrappers.McObjectConverter;
|
import com.seibel.distanthorizons.common.wrappers.McObjectConverter;
|
||||||
import com.seibel.distanthorizons.common.wrappers.world.ClientLevelWrapper;
|
import com.seibel.distanthorizons.common.wrappers.world.ClientLevelWrapper;
|
||||||
import com.seibel.distanthorizons.core.api.internal.ClientApi;
|
import com.seibel.distanthorizons.core.api.internal.ClientApi;
|
||||||
|
import com.seibel.distanthorizons.coreapi.ModInfo;
|
||||||
import com.seibel.distanthorizons.core.util.math.Mat4f;
|
import com.seibel.distanthorizons.core.util.math.Mat4f;
|
||||||
import net.minecraft.client.Camera;
|
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.renderer.GameRenderer;
|
|
||||||
import net.minecraft.client.renderer.LightTexture;
|
|
||||||
import com.seibel.distanthorizons.core.config.Config;
|
|
||||||
import net.minecraft.client.multiplayer.ClientLevel;
|
import net.minecraft.client.multiplayer.ClientLevel;
|
||||||
import net.minecraft.client.renderer.LevelRenderer;
|
import net.minecraft.client.renderer.LevelRenderer;
|
||||||
import net.minecraft.client.renderer.RenderType;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
|
import org.spongepowered.asm.mixin.Unique;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
|
||||||
|
|
||||||
/**
|
import com.seibel.distanthorizons.core.logging.DhLogger;
|
||||||
* This class is used to mix in my rendering code
|
|
||||||
* before Minecraft starts rendering blocks.
|
|
||||||
* If this wasn't done, and we used Forge's
|
|
||||||
* render last event, the LODs would render on top
|
|
||||||
* of the normal terrain.
|
|
||||||
*
|
|
||||||
* This is also the mixin for rendering the clouds
|
|
||||||
*
|
|
||||||
* @author coolGi
|
|
||||||
* @author James Seibel
|
|
||||||
* @version 12-31-2021
|
|
||||||
*/
|
|
||||||
@Mixin(LevelRenderer.class)
|
@Mixin(LevelRenderer.class)
|
||||||
public class MixinLevelRenderer
|
public class MixinLevelRenderer
|
||||||
{
|
{
|
||||||
@Shadow
|
@Shadow
|
||||||
private ClientLevel level;
|
private ClientLevel level;
|
||||||
|
|
||||||
|
@Unique
|
||||||
|
private static final DhLogger LOGGER = new DhLoggerBuilder().build();
|
||||||
|
|
||||||
|
|
||||||
#if MC_VER < MC_1_17_1
|
#if MC_VER < MC_1_17_1
|
||||||
@Inject(at = @At("HEAD"),
|
@Inject(at = @At("HEAD"),
|
||||||
method = "renderChunkLayer(Lnet/minecraft/client/renderer/RenderType;Lcom/mojang/blaze3d/vertex/PoseStack;DDD)V",
|
method = "renderChunkLayer(Lnet/minecraft/client/renderer/RenderType;Lcom/mojang/blaze3d/vertex/PoseStack;DDD)V",
|
||||||
@@ -84,57 +111,94 @@ public class MixinLevelRenderer
|
|||||||
method = "Lnet/minecraft/client/renderer/LevelRenderer;renderSectionLayer(Lnet/minecraft/client/renderer/RenderType;Lcom/mojang/blaze3d/vertex/PoseStack;DDDLorg/joml/Matrix4f;)V",
|
method = "Lnet/minecraft/client/renderer/LevelRenderer;renderSectionLayer(Lnet/minecraft/client/renderer/RenderType;Lcom/mojang/blaze3d/vertex/PoseStack;DDDLorg/joml/Matrix4f;)V",
|
||||||
cancellable = true)
|
cancellable = true)
|
||||||
private void renderChunkLayer(RenderType renderType, PoseStack modelViewMatrixStack, double camX, double camY, double camZ, Matrix4f projectionMatrix, CallbackInfo callback)
|
private void renderChunkLayer(RenderType renderType, PoseStack modelViewMatrixStack, double camX, double camY, double camZ, Matrix4f projectionMatrix, CallbackInfo callback)
|
||||||
#else
|
#elif MC_VER < MC_1_21_6
|
||||||
@Inject(at = @At("HEAD"),
|
@Inject(at = @At("HEAD"),
|
||||||
method = "Lnet/minecraft/client/renderer/LevelRenderer;renderSectionLayer(Lnet/minecraft/client/renderer/RenderType;DDDLorg/joml/Matrix4f;Lorg/joml/Matrix4f;)V",
|
method = "Lnet/minecraft/client/renderer/LevelRenderer;renderSectionLayer(Lnet/minecraft/client/renderer/RenderType;DDDLorg/joml/Matrix4f;Lorg/joml/Matrix4f;)V",
|
||||||
cancellable = true)
|
cancellable = true)
|
||||||
private void renderChunkLayer(RenderType renderType, double x, double y, double z, Matrix4f projectionMatrix, Matrix4f frustumMatrix, CallbackInfo callback)
|
private void renderChunkLayer(RenderType renderType, double x, double y, double z, Matrix4f projectionMatrix, Matrix4f frustumMatrix, CallbackInfo callback)
|
||||||
|
#elif MC_VER < MC_1_21_9
|
||||||
|
@Inject(at = @At("HEAD"), method = "prepareChunkRenders", cancellable = true)
|
||||||
|
private void prepareChunkRenders(Matrix4fc projectionMatrix, double d, double e, double f, CallbackInfoReturnable<ChunkSectionsToRender> callback)
|
||||||
|
#else
|
||||||
|
@Inject(at = @At("HEAD"), method = "renderLevel")
|
||||||
|
private void renderLevel(
|
||||||
|
GraphicsResourceAllocator resourceAllocator, DeltaTracker deltaTracker,
|
||||||
|
boolean renderBlockOutline, Camera camera,
|
||||||
|
Matrix4f positionMatrix, Matrix4f projectionMatrix, Matrix4f idkMatrix, GpuBufferSlice gpuBufferSlice,
|
||||||
|
Vector4f skyColor, boolean thinFog, CallbackInfo callback)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
#if MC_VER == MC_1_16_5
|
#if MC_VER == MC_1_16_5
|
||||||
// get the matrices from the OpenGL fixed pipeline
|
// get the matrices from the OpenGL fixed pipeline
|
||||||
float[] mcProjMatrixRaw = new float[16];
|
float[] mcProjMatrixRaw = new float[16];
|
||||||
GL32.glGetFloatv(GL32.GL_PROJECTION_MATRIX, mcProjMatrixRaw);
|
GL32.glGetFloatv(GL32.GL_PROJECTION_MATRIX, mcProjMatrixRaw);
|
||||||
Mat4f mcProjectionMatrix = new Mat4f(mcProjMatrixRaw);
|
ClientApi.RENDER_STATE.mcProjectionMatrix = new Mat4f(mcProjMatrixRaw);
|
||||||
mcProjectionMatrix.transpose();
|
ClientApi.RENDER_STATE.mcProjectionMatrix.transpose();
|
||||||
|
|
||||||
Mat4f mcModelViewMatrix = McObjectConverter.Convert(matrixStackIn.last().pose());
|
ClientApi.RENDER_STATE.mcModelViewMatrix = McObjectConverter.Convert(matrixStackIn.last().pose());
|
||||||
|
|
||||||
#elif MC_VER <= MC_1_20_4
|
#elif MC_VER <= MC_1_20_4
|
||||||
// get the matrices directly from MC
|
// get the matrices directly from MC
|
||||||
Mat4f mcModelViewMatrix = McObjectConverter.Convert(modelViewMatrixStack.last().pose());
|
ClientApi.RENDER_STATE.mcModelViewMatrix = McObjectConverter.Convert(modelViewMatrixStack.last().pose());
|
||||||
Mat4f mcProjectionMatrix = McObjectConverter.Convert(projectionMatrix);
|
ClientApi.RENDER_STATE.mcProjectionMatrix = McObjectConverter.Convert(projectionMatrix);
|
||||||
|
#elif MC_VER < MC_1_21_9
|
||||||
|
// MC combined the model view and projection matricies
|
||||||
|
ClientApi.RENDER_STATE.mcModelViewMatrix = McObjectConverter.Convert(projectionMatrix);
|
||||||
|
ClientApi.RENDER_STATE.mcProjectionMatrix = new Mat4f();
|
||||||
|
ClientApi.RENDER_STATE.mcProjectionMatrix.setIdentity();
|
||||||
#else
|
#else
|
||||||
// MC combined the model view and projection matricies
|
ClientApi.RENDER_STATE.mcModelViewMatrix = McObjectConverter.Convert(positionMatrix);
|
||||||
Mat4f mcModelViewMatrix = McObjectConverter.Convert(projectionMatrix);
|
ClientApi.RENDER_STATE.mcProjectionMatrix = McObjectConverter.Convert(projectionMatrix);
|
||||||
Mat4f mcProjectionMatrix = new Mat4f();
|
|
||||||
mcProjectionMatrix.setIdentity();
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// TODO move this into a common place
|
// TODO move this into a common place
|
||||||
float frameTime;
|
|
||||||
#if MC_VER < MC_1_21_1
|
#if MC_VER < MC_1_21_1
|
||||||
frameTime = Minecraft.getInstance().getFrameTime();
|
ClientApi.RENDER_STATE.frameTime = Minecraft.getInstance().getFrameTime();
|
||||||
#elif MC_VER < MC_1_21_3
|
#elif MC_VER < MC_1_21_3
|
||||||
frameTime = Minecraft.getInstance().getTimer().getRealtimeDeltaTicks();
|
ClientApi.RENDER_STATE.frameTime = Minecraft.getInstance().getTimer().getRealtimeDeltaTicks();
|
||||||
#else
|
#else
|
||||||
frameTime = Minecraft.getInstance().deltaTracker.getRealtimeDeltaTicks();
|
ClientApi.RENDER_STATE.frameTime = Minecraft.getInstance().deltaTracker.getRealtimeDeltaTicks();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
ClientApi.RENDER_STATE.clientLevelWrapper = ClientLevelWrapper.getWrapperIfDifferent(ClientApi.RENDER_STATE.clientLevelWrapper, this.level);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#if MC_VER < MC_1_21_6
|
||||||
if (renderType.equals(RenderType.translucent()))
|
if (renderType.equals(RenderType.translucent()))
|
||||||
{
|
{
|
||||||
ClientApi.INSTANCE.renderDeferredLods(ClientLevelWrapper.getWrapper(this.level),
|
ClientApi.INSTANCE.renderDeferredLodsForShaders();
|
||||||
mcModelViewMatrix,
|
|
||||||
mcProjectionMatrix,
|
|
||||||
frameTime
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
#elif MC_VER < MC_1_21_9
|
||||||
// FIXME completely disables rendering when sodium is installed
|
// rendering handled via Fabric Api render event
|
||||||
if (Config.Client.Advanced.Debugging.lodOnlyMode.get())
|
#else
|
||||||
{
|
// handled here and in MixinChunkSectionsToRender
|
||||||
callback.cancel();
|
#endif
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#if MC_VER < MC_1_21_9
|
||||||
|
// rendering handled via Fabric Api render event
|
||||||
|
#else
|
||||||
|
@Inject(at = @At("HEAD"), method = "prepareChunkRenders")
|
||||||
|
private void prepareChunkRenders(Matrix4fc modelViewMatrix, double d, double e, double f, CallbackInfoReturnable<ChunkSectionsToRender> callback)
|
||||||
|
{
|
||||||
|
ClientApi.RENDER_STATE.mcModelViewMatrix = McObjectConverter.Convert(modelViewMatrix);
|
||||||
|
ClientApi.RENDER_STATE.clientLevelWrapper = ClientLevelWrapper.getWrapperIfDifferent(ClientApi.RENDER_STATE.clientLevelWrapper, this.level);
|
||||||
|
|
||||||
|
// only crash during development
|
||||||
|
if (ModInfo.IS_DEV_BUILD)
|
||||||
|
{
|
||||||
|
ClientApi.RENDER_STATE.canRenderOrThrow();
|
||||||
|
}
|
||||||
|
|
||||||
|
ClientApi.INSTANCE.renderLods();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+39
-8
@@ -22,49 +22,80 @@ package com.seibel.distanthorizons.fabric.mixins.client;
|
|||||||
import com.seibel.distanthorizons.common.wrappers.minecraft.MinecraftRenderWrapper;
|
import com.seibel.distanthorizons.common.wrappers.minecraft.MinecraftRenderWrapper;
|
||||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
|
||||||
|
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
|
||||||
import net.minecraft.client.renderer.LightTexture;
|
import net.minecraft.client.renderer.LightTexture;
|
||||||
|
|
||||||
import org.spongepowered.asm.mixin.Final;
|
import org.spongepowered.asm.mixin.Final;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
|
import org.spongepowered.asm.mixin.Unique;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
#if MC_VER < MC_1_21_3
|
#if MC_VER < MC_1_21_3
|
||||||
import com.mojang.blaze3d.platform.NativeImage;
|
import com.mojang.blaze3d.platform.NativeImage;
|
||||||
#else
|
#elif MC_VER < MC_1_21_5
|
||||||
import com.mojang.blaze3d.pipeline.TextureTarget;
|
import com.mojang.blaze3d.pipeline.TextureTarget;
|
||||||
|
#else
|
||||||
|
import com.mojang.blaze3d.opengl.GlTexture;
|
||||||
|
import com.mojang.blaze3d.systems.RenderSystem;
|
||||||
|
import com.mojang.blaze3d.textures.GpuTexture;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@Mixin(LightTexture.class)
|
@Mixin(LightTexture.class)
|
||||||
public class MixinLightTexture
|
public class MixinLightTexture
|
||||||
{
|
{
|
||||||
@Shadow
|
|
||||||
@Final
|
|
||||||
#if MC_VER < MC_1_21_3
|
#if MC_VER < MC_1_21_3
|
||||||
|
@Shadow
|
||||||
|
@Final
|
||||||
private NativeImage lightPixels;
|
private NativeImage lightPixels;
|
||||||
#else
|
#elif MC_VER < MC_1_21_5
|
||||||
|
@Shadow
|
||||||
|
@Final
|
||||||
private TextureTarget target;
|
private TextureTarget target;
|
||||||
|
#else
|
||||||
|
@Shadow
|
||||||
|
@Final
|
||||||
|
private GpuTexture texture;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@Unique
|
||||||
|
private MinecraftRenderWrapper renderWrapper = null;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Inject(method = "updateLightTexture(F)V", at = @At("RETURN"))
|
@Inject(method = "updateLightTexture(F)V", at = @At("RETURN"))
|
||||||
public void updateLightTexture(float partialTicks, CallbackInfo ci)
|
public void updateLightTexture(float partialTicks, CallbackInfo ci)
|
||||||
{
|
{
|
||||||
IMinecraftClientWrapper mc = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class);
|
IMinecraftClientWrapper mc = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class);
|
||||||
if (mc == null || mc.getWrappedClientLevel() == null)
|
if (mc == null)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
IClientLevelWrapper clientLevel = mc.getWrappedClientLevel();
|
IClientLevelWrapper clientLevel = mc.getWrappedClientLevel();
|
||||||
|
if (clientLevel == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// lazy initialization to make sure we don't call this too early
|
||||||
|
if (this.renderWrapper == null)
|
||||||
|
{
|
||||||
|
this.renderWrapper = (MinecraftRenderWrapper)SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#if MC_VER < MC_1_21_3
|
#if MC_VER < MC_1_21_3
|
||||||
MinecraftRenderWrapper.INSTANCE.updateLightmap(this.lightPixels, clientLevel);
|
this.renderWrapper.updateLightmap(this.lightPixels, clientLevel);
|
||||||
|
#elif MC_VER < MC_1_21_5
|
||||||
|
this.renderWrapper.setLightmapId(this.target.getColorTextureId(), clientLevel);
|
||||||
#else
|
#else
|
||||||
MinecraftRenderWrapper.INSTANCE.setLightmapId(this.target.getColorTextureId(), clientLevel);
|
GlTexture glTexture = (GlTexture) this.texture;
|
||||||
|
this.renderWrapper.setLightmapId(glTexture.glId(), clientLevel);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -16,7 +16,7 @@ import net.minecraft.client.gui.screens.Screen;
|
|||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.gui.screens.TitleScreen;
|
import net.minecraft.client.gui.screens.TitleScreen;
|
||||||
import net.minecraft.client.multiplayer.ClientLevel;
|
import net.minecraft.client.multiplayer.ClientLevel;
|
||||||
import org.apache.logging.log4j.Logger;
|
import com.seibel.distanthorizons.core.logging.DhLogger;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
import org.spongepowered.asm.mixin.Unique;
|
import org.spongepowered.asm.mixin.Unique;
|
||||||
@@ -34,7 +34,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
|||||||
public abstract class MixinMinecraft
|
public abstract class MixinMinecraft
|
||||||
{
|
{
|
||||||
@Unique
|
@Unique
|
||||||
private static final Logger LOGGER = DhLoggerBuilder.getLogger(MixinMinecraft.class.getSimpleName());
|
private static final DhLogger LOGGER = new DhLoggerBuilder().build();
|
||||||
|
|
||||||
|
|
||||||
@Shadow
|
@Shadow
|
||||||
|
|||||||
+7
@@ -1,12 +1,15 @@
|
|||||||
package com.seibel.distanthorizons.fabric.mixins.client;
|
package com.seibel.distanthorizons.fabric.mixins.client;
|
||||||
|
|
||||||
|
#if MC_VER < MC_1_21_5
|
||||||
import com.mojang.blaze3d.platform.GlStateManager;
|
import com.mojang.blaze3d.platform.GlStateManager;
|
||||||
|
#endif
|
||||||
import com.mojang.blaze3d.platform.TextureUtil;
|
import com.mojang.blaze3d.platform.TextureUtil;
|
||||||
import com.seibel.distanthorizons.core.config.Config;
|
import com.seibel.distanthorizons.core.config.Config;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets Minecraft's LOD Bias (looks similar to mipmaps)
|
* Sets Minecraft's LOD Bias (looks similar to mipmaps)
|
||||||
*
|
*
|
||||||
@@ -15,6 +18,9 @@ import org.spongepowered.asm.mixin.injection.Redirect;
|
|||||||
@Mixin(TextureUtil.class)
|
@Mixin(TextureUtil.class)
|
||||||
public class MixinTextureUtil
|
public class MixinTextureUtil
|
||||||
{
|
{
|
||||||
|
// TODO fix for MC 1.21.5+
|
||||||
|
|
||||||
|
#if MC_VER < MC_1_21_5
|
||||||
@Redirect(method = "Lcom/mojang/blaze3d/platform/TextureUtil;prepareImage(Lcom/mojang/blaze3d/platform/NativeImage$InternalGlFormat;IIII)V",
|
@Redirect(method = "Lcom/mojang/blaze3d/platform/TextureUtil;prepareImage(Lcom/mojang/blaze3d/platform/NativeImage$InternalGlFormat;IIII)V",
|
||||||
at = @At(value = "INVOKE", target = "Lcom/mojang/blaze3d/platform/GlStateManager;_texParameter(IIF)V", #if MC_VER == MC_1_16_5 remap = true #else remap = false #endif))
|
at = @At(value = "INVOKE", target = "Lcom/mojang/blaze3d/platform/GlStateManager;_texParameter(IIF)V", #if MC_VER == MC_1_16_5 remap = true #else remap = false #endif))
|
||||||
private static void setLodBias(int target, int pname, float param)
|
private static void setLodBias(int target, int pname, float param)
|
||||||
@@ -27,5 +33,6 @@ public class MixinTextureUtil
|
|||||||
GlStateManager._texParameter(target, pname, biasValue);
|
GlStateManager._texParameter(target, pname, biasValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+48
@@ -0,0 +1,48 @@
|
|||||||
|
package com.seibel.distanthorizons.fabric.mixins.server;
|
||||||
|
|
||||||
|
#if MC_VER < MC_1_21_4
|
||||||
|
|
||||||
|
import net.minecraft.world.entity.Entity;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
|
||||||
|
@Mixin(Entity.class)
|
||||||
|
public class MixinLevelTicks<T>
|
||||||
|
{
|
||||||
|
// dummy mixin to make the loader happy
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
import com.seibel.distanthorizons.common.wrappers.DependencySetupDoneCheck;
|
||||||
|
|
||||||
|
import net.minecraft.world.ticks.LevelTicks;
|
||||||
|
import net.minecraft.world.ticks.ScheduledTick;
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
@Mixin(LevelTicks.class) // available in 1.18.2+, but only needed in 1.21.4+
|
||||||
|
public class MixinLevelTicks<T>
|
||||||
|
{
|
||||||
|
// TODO put in a common location
|
||||||
|
private static boolean isWorldGenThread()
|
||||||
|
{ return DependencySetupDoneCheck.isDone && DependencySetupDoneCheck.getIsCurrentThreadDistantGeneratorThread.get(); }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Inject(method = "schedule", at = @At(value = "HEAD"), cancellable = true)
|
||||||
|
private void onChunkSave(ScheduledTick<T> tick, CallbackInfo ci)
|
||||||
|
{
|
||||||
|
// In MC 1.21.4 an error check was added to log attempting to schedule ticks for unloaded chunks
|
||||||
|
// this caused a lot of unnecessary errors when generating sand (FallingBlock.class).
|
||||||
|
if (isWorldGenThread())
|
||||||
|
{
|
||||||
|
ci.cancel();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
+64
@@ -0,0 +1,64 @@
|
|||||||
|
package com.seibel.distanthorizons.fabric.testing;
|
||||||
|
|
||||||
|
import com.seibel.distanthorizons.api.DhApi;
|
||||||
|
import com.seibel.distanthorizons.api.interfaces.block.IDhApiBlockStateWrapper;
|
||||||
|
import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiChunkProcessingEvent;
|
||||||
|
import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiEventParam;
|
||||||
|
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||||
|
import com.seibel.distanthorizons.core.logging.DhLogger;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public class TestChunkInputReplacerEvent extends DhApiChunkProcessingEvent
|
||||||
|
{
|
||||||
|
private static final DhLogger LOGGER = new DhLoggerBuilder().build();
|
||||||
|
|
||||||
|
private static final String REPLACEMENT_BLOCK_STATE_NAMESPACE = "minecraft:stone";
|
||||||
|
|
||||||
|
private IDhApiBlockStateWrapper stoneBlockWrapper = null;
|
||||||
|
private boolean initialBlockSetupComplete = false;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void blockOrBiomeChangedDuringChunkProcessing(DhApiEventParam<EventParam> event)
|
||||||
|
{
|
||||||
|
if (!this.initialBlockSetupComplete)
|
||||||
|
{
|
||||||
|
// this method can be called on multiple threads
|
||||||
|
synchronized (this)
|
||||||
|
{
|
||||||
|
this.initialBlockSetupComplete = true;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
this.stoneBlockWrapper = DhApi.Delayed.wrapperFactory.getDefaultBlockStateWrapper(REPLACEMENT_BLOCK_STATE_NAMESPACE, event.value.levelWrapper);
|
||||||
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
LOGGER.error("Unable to get ["+REPLACEMENT_BLOCK_STATE_NAMESPACE+"] block replacement cannot continue and is now disabled, error: ["+e.getMessage()+"].", e);
|
||||||
|
DhApi.events.unbind(DhApiChunkProcessingEvent.class, this.getClass());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// will happen if the initial setup fails until the unbind call is processed
|
||||||
|
// which likely won't happen until the current chunk has finished processing
|
||||||
|
if (this.stoneBlockWrapper == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// replace any dirt or grass block with stone
|
||||||
|
IDhApiBlockStateWrapper block = event.value.currentBlock;
|
||||||
|
if (block.getSerialString().contains("grass_block")
|
||||||
|
|| block.getSerialString().contains("dirt"))
|
||||||
|
{
|
||||||
|
event.value.setBlockOverride(this.stoneBlockWrapper);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
-2
@@ -10,11 +10,9 @@ import com.seibel.distanthorizons.api.interfaces.world.IDhApiLevelWrapper;
|
|||||||
import com.seibel.distanthorizons.api.objects.data.DhApiChunk;
|
import com.seibel.distanthorizons.api.objects.data.DhApiChunk;
|
||||||
import com.seibel.distanthorizons.api.objects.data.DhApiTerrainDataPoint;
|
import com.seibel.distanthorizons.api.objects.data.DhApiTerrainDataPoint;
|
||||||
import com.seibel.distanthorizons.common.wrappers.world.ServerLevelWrapper;
|
import com.seibel.distanthorizons.common.wrappers.world.ServerLevelWrapper;
|
||||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.server.level.ServerLevel;
|
import net.minecraft.server.level.ServerLevel;
|
||||||
import net.minecraft.world.level.chunk.ChunkAccess;
|
import net.minecraft.world.level.chunk.ChunkAccess;
|
||||||
import org.apache.logging.log4j.Logger;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -13,7 +13,7 @@ import com.seibel.distanthorizons.api.objects.data.IDhApiFullDataSource;
|
|||||||
import com.seibel.distanthorizons.common.wrappers.world.ServerLevelWrapper;
|
import com.seibel.distanthorizons.common.wrappers.world.ServerLevelWrapper;
|
||||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||||
import net.minecraft.server.level.ServerLevel;
|
import net.minecraft.server.level.ServerLevel;
|
||||||
import org.apache.logging.log4j.Logger;
|
import com.seibel.distanthorizons.core.logging.DhLogger;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -23,7 +23,7 @@ import java.util.function.Consumer;
|
|||||||
|
|
||||||
public class TestGenericWorldGenerator implements IDhApiWorldGenerator
|
public class TestGenericWorldGenerator implements IDhApiWorldGenerator
|
||||||
{
|
{
|
||||||
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
|
private static final DhLogger LOGGER = new DhLoggerBuilder().build();
|
||||||
|
|
||||||
private final IDhApiLevelWrapper levelWrapper;
|
private final IDhApiLevelWrapper levelWrapper;
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -6,12 +6,12 @@ import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiLevelLo
|
|||||||
import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiEventParam;
|
import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiEventParam;
|
||||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||||
import net.minecraft.server.level.ServerLevel;
|
import net.minecraft.server.level.ServerLevel;
|
||||||
import org.apache.logging.log4j.Logger;
|
import com.seibel.distanthorizons.core.logging.DhLogger;
|
||||||
|
|
||||||
// TODO add to API example once Builderb0y has given the all-clear
|
// TODO add to API example once Builderb0y has given the all-clear
|
||||||
public class TestWorldGenBindingEvent extends DhApiLevelLoadEvent
|
public class TestWorldGenBindingEvent extends DhApiLevelLoadEvent
|
||||||
{
|
{
|
||||||
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
|
private static final DhLogger LOGGER = new DhLoggerBuilder().build();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onLevelLoad(DhApiEventParam<DhApiLevelLoadEvent.EventParam> event)
|
public void onLevelLoad(DhApiEventParam<DhApiLevelLoadEvent.EventParam> event)
|
||||||
|
|||||||
+12
-2
@@ -43,11 +43,22 @@ import net.minecraft.world.phys.AABB;
|
|||||||
|
|
||||||
public class SodiumAccessor implements ISodiumAccessor
|
public class SodiumAccessor implements ISodiumAccessor
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* True if sodium 0.5 or less is present. <br>
|
||||||
|
* This field is public because it's also used to check if we need Indium to be present. <br>
|
||||||
|
* We need Indium if Sodium 0.5 or less is present.
|
||||||
|
*/
|
||||||
|
public static final boolean isSodiumV5OrLess;
|
||||||
|
|
||||||
#if MC_VER >= MC_1_20_1
|
#if MC_VER >= MC_1_20_1
|
||||||
private static MethodHandle setFogOcclusionMethod;
|
private static MethodHandle setFogOcclusionMethod;
|
||||||
private static Object sodiumPerformanceOptions;
|
private static Object sodiumPerformanceOptions;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static {
|
||||||
|
isSodiumV5OrLess = !classPresent("net.caffeinemc.mods.sodium.client.render.SodiumWorldRenderer");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//======================//
|
//======================//
|
||||||
@@ -72,8 +83,7 @@ public class SodiumAccessor implements ISodiumAccessor
|
|||||||
{
|
{
|
||||||
if (sodiumPerformanceOptions == null)
|
if (sodiumPerformanceOptions == null)
|
||||||
{
|
{
|
||||||
boolean sodiumV6 = classPresent("net.caffeinemc.mods.sodium.client.render.SodiumWorldRenderer");
|
if (isSodiumV5OrLess)
|
||||||
if (!sodiumV6)
|
|
||||||
{
|
{
|
||||||
// sodium 0.5
|
// sodium 0.5
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,8 @@
|
|||||||
"server.MixinEntity",
|
"server.MixinEntity",
|
||||||
"server.MixinServerPlayer",
|
"server.MixinServerPlayer",
|
||||||
"server.MixinTracingExecutor",
|
"server.MixinTracingExecutor",
|
||||||
"server.MixinUtilBackgroundThread"
|
"server.MixinUtilBackgroundThread",
|
||||||
|
"server.MixinLevelTicks"
|
||||||
],
|
],
|
||||||
"client": [
|
"client": [
|
||||||
"client.MixinClientLevel",
|
"client.MixinClientLevel",
|
||||||
@@ -16,6 +17,7 @@
|
|||||||
"client.MixinDebugScreenOverlay",
|
"client.MixinDebugScreenOverlay",
|
||||||
"client.MixinFogRenderer",
|
"client.MixinFogRenderer",
|
||||||
"client.MixinLevelRenderer",
|
"client.MixinLevelRenderer",
|
||||||
|
"client.MixinChunkSectionsToRender",
|
||||||
"client.MixinLightTexture",
|
"client.MixinLightTexture",
|
||||||
"client.MixinMinecraft",
|
"client.MixinMinecraft",
|
||||||
"client.MixinOptionsScreen",
|
"client.MixinOptionsScreen",
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ import com.seibel.distanthorizons.core.util.threading.ThreadPoolUtil;
|
|||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.chunk.IChunkWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.chunk.IChunkWrapper;
|
||||||
|
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
|
||||||
|
import com.seibel.distanthorizons.core.wrapperInterfaces.misc.IPluginPacketSender;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.misc.IServerPlayerWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.misc.IServerPlayerWrapper;
|
||||||
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;
|
||||||
@@ -54,7 +55,7 @@ import net.minecraftforge.event.entity.player.PlayerInteractEvent;
|
|||||||
import net.minecraft.world.level.chunk.ChunkAccess;
|
import net.minecraft.world.level.chunk.ChunkAccess;
|
||||||
|
|
||||||
import net.minecraftforge.common.MinecraftForge;
|
import net.minecraftforge.common.MinecraftForge;
|
||||||
import org.apache.logging.log4j.Logger;
|
import com.seibel.distanthorizons.core.logging.DhLogger;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.lwjgl.glfw.GLFW;
|
import org.lwjgl.glfw.GLFW;
|
||||||
|
|
||||||
@@ -79,7 +80,8 @@ import java.util.concurrent.ThreadPoolExecutor;
|
|||||||
public class ForgeClientProxy implements AbstractModInitializer.IEventProxy
|
public class ForgeClientProxy implements AbstractModInitializer.IEventProxy
|
||||||
{
|
{
|
||||||
private static final IMinecraftClientWrapper MC = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class);
|
private static final IMinecraftClientWrapper MC = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class);
|
||||||
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
|
private static final ForgePluginPacketSender PACKET_SENDER = (ForgePluginPacketSender) SingletonInjector.INSTANCE.get(IPluginPacketSender.class);
|
||||||
|
private static final DhLogger LOGGER = new DhLoggerBuilder().build();
|
||||||
|
|
||||||
|
|
||||||
#if MC_VER < MC_1_19_2
|
#if MC_VER < MC_1_19_2
|
||||||
@@ -96,7 +98,7 @@ public class ForgeClientProxy implements AbstractModInitializer.IEventProxy
|
|||||||
MinecraftForge.EVENT_BUS.register(this);
|
MinecraftForge.EVENT_BUS.register(this);
|
||||||
|
|
||||||
// handles singleplayer, LAN, and connecting to a server
|
// handles singleplayer, LAN, and connecting to a server
|
||||||
ForgePluginPacketSender.setPacketHandler((IServerPlayerWrapper player, @NotNull AbstractNetworkMessage message) ->
|
PACKET_SENDER.setPacketHandler((IServerPlayerWrapper player, @NotNull AbstractNetworkMessage message) ->
|
||||||
{
|
{
|
||||||
ClientApi.INSTANCE.pluginMessageReceived(message);
|
ClientApi.INSTANCE.pluginMessageReceived(message);
|
||||||
ServerApi.INSTANCE.pluginMessageReceived(player, message);
|
ServerApi.INSTANCE.pluginMessageReceived(player, message);
|
||||||
|
|||||||
@@ -86,11 +86,13 @@ public class ForgeMain extends AbstractModInitializer
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void createInitialBindings()
|
protected void createInitialSharedBindings()
|
||||||
{
|
{
|
||||||
SingletonInjector.INSTANCE.bind(IModChecker.class, ModChecker.INSTANCE);
|
SingletonInjector.INSTANCE.bind(IModChecker.class, ModChecker.INSTANCE);
|
||||||
SingletonInjector.INSTANCE.bind(IPluginPacketSender.class, new ForgePluginPacketSender());
|
SingletonInjector.INSTANCE.bind(IPluginPacketSender.class, new ForgePluginPacketSender());
|
||||||
}
|
}
|
||||||
|
@Override
|
||||||
|
protected void createInitialClientBindings() { /* no additional setup needed currently */ }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected IEventProxy createClientProxy() { return new ForgeClientProxy(); }
|
protected IEventProxy createClientProxy() { return new ForgeClientProxy(); }
|
||||||
@@ -118,14 +120,14 @@ public class ForgeMain extends AbstractModInitializer
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void subscribeRegisterCommandsEvent(Consumer<CommandDispatcher<CommandSourceStack>> eventHandler)
|
protected void subscribeRegisterCommandsEvent(Consumer<CommandDispatcher<CommandSourceStack>> eventHandler)
|
||||||
{
|
{ MinecraftForge.EVENT_BUS.addListener((RegisterCommandsEvent e) -> { eventHandler.accept(e.getDispatcher()); }); }
|
||||||
MinecraftForge.EVENT_BUS.addListener((RegisterCommandsEvent e) -> { eventHandler.accept(e.getDispatcher()); });
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void subscribeClientStartedEvent(Runnable eventHandler)
|
protected void subscribeClientStartedEvent(Runnable eventHandler)
|
||||||
{
|
{
|
||||||
// FIXME What event is this?
|
// Just run the event handler, since there are no proper ClientLifecycleEvent for the client
|
||||||
|
// to signify readiness other than FmlClientSetupEvent
|
||||||
|
eventHandler.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -45,16 +45,18 @@ public class ForgePluginPacketSender extends AbstractPluginPacketSender
|
|||||||
);
|
);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
public static void setPacketHandler(Consumer<AbstractNetworkMessage> consumer)
|
public ForgePluginPacketSender() { super(true); }
|
||||||
|
|
||||||
|
public void setPacketHandler(Consumer<AbstractNetworkMessage> consumer)
|
||||||
{
|
{
|
||||||
setPacketHandler((player, message) -> consumer.accept(message));
|
this.setPacketHandler((player, message) -> consumer.accept(message));
|
||||||
}
|
}
|
||||||
public static void setPacketHandler(BiConsumer<IServerPlayerWrapper, AbstractNetworkMessage> consumer)
|
public void setPacketHandler(BiConsumer<IServerPlayerWrapper, AbstractNetworkMessage> consumer)
|
||||||
{
|
{
|
||||||
#if MC_VER >= MC_1_20_2
|
#if MC_VER >= MC_1_20_2
|
||||||
PLUGIN_CHANNEL.messageBuilder(MessageWrapper.class, 0)
|
PLUGIN_CHANNEL.messageBuilder(MessageWrapper.class, 0)
|
||||||
.encoder((wrapper, out) -> AbstractPluginPacketSender.encodeMessage(out, wrapper.message))
|
.encoder((wrapper, out) -> this.encodeMessage(out, wrapper.message))
|
||||||
.decoder(in -> new MessageWrapper(AbstractPluginPacketSender.decodeMessage(in)))
|
.decoder(in -> new MessageWrapper(this.decodeMessage(in)))
|
||||||
.consumerNetworkThread((wrapper, context) ->
|
.consumerNetworkThread((wrapper, context) ->
|
||||||
{
|
{
|
||||||
if (wrapper.message != null)
|
if (wrapper.message != null)
|
||||||
@@ -73,8 +75,8 @@ public class ForgePluginPacketSender extends AbstractPluginPacketSender
|
|||||||
.add();
|
.add();
|
||||||
#else // < 1.20.2
|
#else // < 1.20.2
|
||||||
PLUGIN_CHANNEL.registerMessage(0, MessageWrapper.class,
|
PLUGIN_CHANNEL.registerMessage(0, MessageWrapper.class,
|
||||||
(wrapper, out) -> AbstractPluginPacketSender.encodeMessage(out, wrapper.message),
|
(wrapper, out) -> this.encodeMessage(out, wrapper.message),
|
||||||
in -> new MessageWrapper(AbstractPluginPacketSender.decodeMessage(in)),
|
in -> new MessageWrapper(this.decodeMessage(in)),
|
||||||
(wrapper, context) ->
|
(wrapper, context) ->
|
||||||
{
|
{
|
||||||
if (wrapper.message != null)
|
if (wrapper.message != null)
|
||||||
|
|||||||
@@ -7,7 +7,9 @@ import com.seibel.distanthorizons.common.wrappers.misc.ServerPlayerWrapper;
|
|||||||
import com.seibel.distanthorizons.common.wrappers.world.ServerLevelWrapper;
|
import com.seibel.distanthorizons.common.wrappers.world.ServerLevelWrapper;
|
||||||
import com.seibel.distanthorizons.common.wrappers.worldGeneration.BatchGenerationEnvironment;
|
import com.seibel.distanthorizons.common.wrappers.worldGeneration.BatchGenerationEnvironment;
|
||||||
import com.seibel.distanthorizons.core.api.internal.ServerApi;
|
import com.seibel.distanthorizons.core.api.internal.ServerApi;
|
||||||
|
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.chunk.IChunkWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.chunk.IChunkWrapper;
|
||||||
|
import com.seibel.distanthorizons.core.wrapperInterfaces.misc.IPluginPacketSender;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper;
|
||||||
import net.minecraft.resources.ResourceKey;
|
import net.minecraft.resources.ResourceKey;
|
||||||
import net.minecraft.server.level.ServerLevel;
|
import net.minecraft.server.level.ServerLevel;
|
||||||
@@ -45,12 +47,14 @@ import net.minecraftforge.event.server.ServerStoppingEvent;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
import org.apache.logging.log4j.Logger;
|
import com.seibel.distanthorizons.core.logging.DhLogger;
|
||||||
|
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
public class ForgeServerProxy implements AbstractModInitializer.IEventProxy
|
public class ForgeServerProxy implements AbstractModInitializer.IEventProxy
|
||||||
{
|
{
|
||||||
|
private static final ForgePluginPacketSender PACKET_SENDER = (ForgePluginPacketSender) SingletonInjector.INSTANCE.get(IPluginPacketSender.class);
|
||||||
|
|
||||||
#if MC_VER < MC_1_19_2
|
#if MC_VER < MC_1_19_2
|
||||||
private static LevelAccessor GetEventLevel(WorldEvent e) { return e.getWorld(); }
|
private static LevelAccessor GetEventLevel(WorldEvent e) { return e.getWorld(); }
|
||||||
#else
|
#else
|
||||||
@@ -68,7 +72,7 @@ public class ForgeServerProxy implements AbstractModInitializer.IEventProxy
|
|||||||
MinecraftForge.EVENT_BUS.register(this);
|
MinecraftForge.EVENT_BUS.register(this);
|
||||||
if (this.isDedicated)
|
if (this.isDedicated)
|
||||||
{
|
{
|
||||||
ForgePluginPacketSender.setPacketHandler(ServerApi.INSTANCE::pluginMessageReceived);
|
PACKET_SENDER.setPacketHandler(ServerApi.INSTANCE::pluginMessageReceived);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+13
-28
@@ -129,34 +129,35 @@ public class MixinLevelRenderer
|
|||||||
// get the matrices from the OpenGL fixed pipeline
|
// get the matrices from the OpenGL fixed pipeline
|
||||||
float[] mcProjMatrixRaw = new float[16];
|
float[] mcProjMatrixRaw = new float[16];
|
||||||
GL15.glGetFloatv(GL15.GL_PROJECTION_MATRIX, mcProjMatrixRaw);
|
GL15.glGetFloatv(GL15.GL_PROJECTION_MATRIX, mcProjMatrixRaw);
|
||||||
Mat4f mcProjectionMatrix = new Mat4f(mcProjMatrixRaw);
|
ClientApi.RENDER_STATE.mcProjectionMatrix = new Mat4f(mcProjMatrixRaw);
|
||||||
mcProjectionMatrix.transpose();
|
ClientApi.RENDER_STATE.mcProjectionMatrix.transpose();
|
||||||
|
|
||||||
Mat4f mcModelViewMatrix = McObjectConverter.Convert(matrixStackIn.last().pose());
|
ClientApi.RENDER_STATE.mcModelViewMatrix = McObjectConverter.Convert(matrixStackIn.last().pose());
|
||||||
|
|
||||||
#else
|
#else
|
||||||
// get the matrices directly from MC
|
// get the matrices directly from MC
|
||||||
Mat4f mcModelViewMatrix = McObjectConverter.Convert(modelViewMatrixStack.last().pose());
|
ClientApi.RENDER_STATE.mcModelViewMatrix = McObjectConverter.Convert(modelViewMatrixStack.last().pose());
|
||||||
Mat4f mcProjectionMatrix = McObjectConverter.Convert(projectionMatrix);
|
ClientApi.RENDER_STATE.mcProjectionMatrix = McObjectConverter.Convert(projectionMatrix);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
float frameTime;
|
|
||||||
#if MC_VER < MC_1_21_1
|
#if MC_VER < MC_1_21_1
|
||||||
frameTime = Minecraft.getInstance().getFrameTime();
|
ClientApi.RENDER_STATE.frameTime = Minecraft.getInstance().getFrameTime();
|
||||||
#else
|
#else
|
||||||
frameTime = Minecraft.getInstance().getTimer().getRealtimeDeltaTicks();
|
ClientApi.RENDER_STATE.frameTime = Minecraft.getInstance().getTimer().getRealtimeDeltaTicks();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
ClientApi.RENDER_STATE.clientLevelWrapper = ClientLevelWrapper.getWrapperIfDifferent(ClientApi.RENDER_STATE.clientLevelWrapper, this.level);
|
||||||
|
|
||||||
|
|
||||||
// only render before solid blocks
|
// only render before solid blocks
|
||||||
if (renderType.equals(RenderType.solid()))
|
if (renderType.equals(RenderType.solid()))
|
||||||
{
|
{
|
||||||
ClientApi.INSTANCE.renderLods(ClientLevelWrapper.getWrapper(this.level), mcModelViewMatrix, mcProjectionMatrix, frameTime);
|
ClientApi.INSTANCE.renderLods();
|
||||||
}
|
}
|
||||||
else if (renderType.equals(RenderType.translucent()))
|
else if (renderType.equals(RenderType.translucent()))
|
||||||
{
|
{
|
||||||
ClientApi.INSTANCE.renderDeferredLods(ClientLevelWrapper.getWrapper(this.level), mcModelViewMatrix, mcProjectionMatrix, frameTime);
|
ClientApi.INSTANCE.renderDeferredLodsForShaders();
|
||||||
}
|
}
|
||||||
|
|
||||||
// render fade
|
// render fade
|
||||||
@@ -165,27 +166,11 @@ public class MixinLevelRenderer
|
|||||||
// we need to trigger for the renderType after those passes are done
|
// we need to trigger for the renderType after those passes are done
|
||||||
if (renderType.equals(RenderType.cutout()))
|
if (renderType.equals(RenderType.cutout()))
|
||||||
{
|
{
|
||||||
ClientApi.INSTANCE.renderFadeOpaque(
|
ClientApi.INSTANCE.renderFadeOpaque();
|
||||||
mcModelViewMatrix,
|
|
||||||
mcProjectionMatrix,
|
|
||||||
frameTime,
|
|
||||||
ClientLevelWrapper.getWrapper(this.level)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
else if (renderType.equals(RenderType.tripwire()))
|
else if (renderType.equals(RenderType.tripwire()))
|
||||||
{
|
{
|
||||||
ClientApi.INSTANCE.renderFade(
|
ClientApi.INSTANCE.renderFadeTransparent();
|
||||||
mcModelViewMatrix,
|
|
||||||
mcProjectionMatrix,
|
|
||||||
frameTime,
|
|
||||||
ClientLevelWrapper.getWrapper(this.level)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (Config.Client.Advanced.Debugging.lodOnlyMode.get())
|
|
||||||
{
|
|
||||||
callback.cancel();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -12,7 +12,7 @@ import com.seibel.distanthorizons.core.wrapperInterfaces.IVersionConstants;
|
|||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.gui.screens.Screen;
|
import net.minecraft.client.gui.screens.Screen;
|
||||||
import net.minecraft.client.gui.screens.TitleScreen;
|
import net.minecraft.client.gui.screens.TitleScreen;
|
||||||
import org.apache.logging.log4j.Logger;
|
import com.seibel.distanthorizons.core.logging.DhLogger;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.Unique;
|
import org.spongepowered.asm.mixin.Unique;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
@@ -29,7 +29,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
|||||||
public class MixinMinecraft
|
public class MixinMinecraft
|
||||||
{
|
{
|
||||||
@Unique
|
@Unique
|
||||||
private static final Logger LOGGER = DhLoggerBuilder.getLogger(MixinMinecraft.class.getSimpleName());
|
private static final DhLogger LOGGER = new DhLoggerBuilder().build();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+10
-6
@@ -5,8 +5,8 @@ org.gradle.caching=true
|
|||||||
|
|
||||||
# Mod Info
|
# Mod Info
|
||||||
mod_name=DistantHorizons
|
mod_name=DistantHorizons
|
||||||
mod_version=2.3.1-b
|
mod_version=2.3.7-b-dev
|
||||||
api_version=4.0.0
|
api_version=5.0.0
|
||||||
maven_group=com.seibel.distanthorizons
|
maven_group=com.seibel.distanthorizons
|
||||||
mod_readable_name=Distant Horizons
|
mod_readable_name=Distant Horizons
|
||||||
mod_description=This mod generates and renders simplified terrain beyond the normal view distance at a low performance cost. Allowing you to see much farther without turning your game into a slideshow.
|
mod_description=This mod generates and renders simplified terrain beyond the normal view distance at a low performance cost. Allowing you to see much farther without turning your game into a slideshow.
|
||||||
@@ -18,20 +18,24 @@ mod_issues=https://gitlab.com/jeseibel/distant-horizons/-/issues
|
|||||||
mod_discord=https://discord.gg/xAB8G4cENx
|
mod_discord=https://discord.gg/xAB8G4cENx
|
||||||
|
|
||||||
# Global Plugin Versions
|
# Global Plugin Versions
|
||||||
manifold_version=2024.1.37
|
manifold_version=2025.1.27
|
||||||
# 2023.1.17 can be used if there are mystery Java compiler issues
|
# 2023.1.17 can be used if there are mystery Java compiler issues
|
||||||
nightconfig_version=3.6.6
|
nightconfig_version=3.6.6
|
||||||
lz4_version=1.8.0
|
lz4_version=1.8.0
|
||||||
xz_version=1.9
|
xz_version=1.9
|
||||||
|
zstd_version=1.5.7-6
|
||||||
|
# Before updating, read relocate_natives/README.md
|
||||||
sqlite_jdbc_version=3.47.2.0
|
sqlite_jdbc_version=3.47.2.0
|
||||||
# 8.2.1 is the newest version we can use since that's the version MC 1.16.5 uses
|
# 8.2.1 is the newest version we can use since that's the version MC 1.16.5 uses
|
||||||
# (at least until we can fix the gradle script so core and main can use/shade different fastutil versions)
|
|
||||||
fastutil_version=8.2.1
|
fastutil_version=8.2.1
|
||||||
#svgSalamander_version=1.1.3
|
#svgSalamander_version=1.1.3
|
||||||
|
|
||||||
# Minecraft related libraries (included in MC's jar)
|
# Minecraft related libraries (included in MC's jar)
|
||||||
log4j_version=2.23.1
|
log4j_version=2.23.1
|
||||||
lwjgl_version=3.3.1
|
# if we actually want to use LWJGL methods, this needs to be a MC version variable
|
||||||
|
# since different MC versions have different LWJGL versions that aren't compatible
|
||||||
|
# 3.3.3 is for MC 1.21.8
|
||||||
|
lwjgl_version=3.3.3
|
||||||
joml_version=1.10.2
|
joml_version=1.10.2
|
||||||
|
|
||||||
# Architectury config
|
# Architectury config
|
||||||
@@ -51,7 +55,7 @@ versionStr=
|
|||||||
|
|
||||||
# This defines what MC version Intellij will use for the preprocessor
|
# This defines what MC version Intellij will use for the preprocessor
|
||||||
# and what version is used automatically by build and run commands
|
# and what version is used automatically by build and run commands
|
||||||
mcVer=1.21.4
|
mcVer=1.21.10
|
||||||
|
|
||||||
# Defines the maximum amount of memory Minecraft is allowed when run in a development environment
|
# Defines the maximum amount of memory Minecraft is allowed when run in a development environment
|
||||||
#minecraftMemoryJavaArg="-Xmx4G"
|
#minecraftMemoryJavaArg="-Xmx4G"
|
||||||
|
|||||||
+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.10-bin.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-bin.zip
|
||||||
networkTimeout=10000
|
networkTimeout=10000
|
||||||
validateDistributionUrl=true
|
validateDistributionUrl=true
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
|
|||||||
+55
-39
@@ -21,16 +21,13 @@ package com.seibel.distanthorizons.neoforge;
|
|||||||
|
|
||||||
import com.seibel.distanthorizons.common.AbstractModInitializer;
|
import com.seibel.distanthorizons.common.AbstractModInitializer;
|
||||||
import com.seibel.distanthorizons.common.util.ProxyUtil;
|
import com.seibel.distanthorizons.common.util.ProxyUtil;
|
||||||
import com.seibel.distanthorizons.common.wrappers.McObjectConverter;
|
|
||||||
import com.seibel.distanthorizons.common.wrappers.minecraft.MinecraftRenderWrapper;
|
import com.seibel.distanthorizons.common.wrappers.minecraft.MinecraftRenderWrapper;
|
||||||
import com.seibel.distanthorizons.common.wrappers.world.ClientLevelWrapper;
|
import com.seibel.distanthorizons.common.wrappers.world.ClientLevelWrapper;
|
||||||
import com.seibel.distanthorizons.core.api.internal.ClientApi;
|
import com.seibel.distanthorizons.core.api.internal.ClientApi;
|
||||||
import com.seibel.distanthorizons.core.api.internal.SharedApi;
|
import com.seibel.distanthorizons.core.api.internal.SharedApi;
|
||||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||||
import com.seibel.distanthorizons.core.util.math.Mat4f;
|
|
||||||
import com.seibel.distanthorizons.core.util.threading.ThreadPoolUtil;
|
import com.seibel.distanthorizons.core.util.threading.ThreadPoolUtil;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.chunk.IChunkWrapper;
|
|
||||||
|
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
|
||||||
@@ -40,13 +37,12 @@ import net.minecraft.world.level.LevelAccessor;
|
|||||||
import net.minecraft.client.multiplayer.ClientLevel;
|
import net.minecraft.client.multiplayer.ClientLevel;
|
||||||
import net.neoforged.neoforge.client.event.RenderLevelStageEvent;
|
import net.neoforged.neoforge.client.event.RenderLevelStageEvent;
|
||||||
import net.neoforged.neoforge.common.NeoForge;
|
import net.neoforged.neoforge.common.NeoForge;
|
||||||
import net.neoforged.neoforge.event.level.ChunkEvent;
|
|
||||||
import net.neoforged.neoforge.event.level.LevelEvent;
|
import net.neoforged.neoforge.event.level.LevelEvent;
|
||||||
|
|
||||||
import net.neoforged.neoforge.event.entity.player.PlayerInteractEvent;
|
import net.neoforged.neoforge.event.entity.player.PlayerInteractEvent;
|
||||||
import net.minecraft.world.level.chunk.ChunkAccess;
|
import net.minecraft.world.level.chunk.ChunkAccess;
|
||||||
|
|
||||||
import org.apache.logging.log4j.Logger;
|
import com.seibel.distanthorizons.core.logging.DhLogger;
|
||||||
import org.lwjgl.glfw.GLFW;
|
import org.lwjgl.glfw.GLFW;
|
||||||
|
|
||||||
import com.seibel.distanthorizons.common.wrappers.chunk.ChunkWrapper;
|
import com.seibel.distanthorizons.common.wrappers.chunk.ChunkWrapper;
|
||||||
@@ -62,29 +58,14 @@ import net.neoforged.neoforge.event.TickEvent;
|
|||||||
import net.neoforged.neoforge.client.event.ClientTickEvent;
|
import net.neoforged.neoforge.client.event.ClientTickEvent;
|
||||||
|
|
||||||
import java.util.concurrent.AbstractExecutorService;
|
import java.util.concurrent.AbstractExecutorService;
|
||||||
import java.util.concurrent.ThreadPoolExecutor;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This handles all events sent to the client,
|
|
||||||
* and is the starting point for most of the mod.
|
|
||||||
*
|
|
||||||
* @author James_Seibel
|
|
||||||
* @version 2023-7-27
|
|
||||||
*/
|
|
||||||
public class NeoforgeClientProxy implements AbstractModInitializer.IEventProxy
|
public class NeoforgeClientProxy implements AbstractModInitializer.IEventProxy
|
||||||
{
|
{
|
||||||
private static final IMinecraftClientWrapper MC = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class);
|
private static final IMinecraftClientWrapper MC = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class);
|
||||||
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
|
private static final DhLogger LOGGER = new DhLoggerBuilder().build();
|
||||||
|
|
||||||
// private static SimpleChannel multiversePluginChannel;
|
|
||||||
|
|
||||||
// Not the cleanest way of passing this to the LOD renderer, but it'll have to do for now
|
|
||||||
public static Mat4f currentModelViewMatrix = new Mat4f();
|
|
||||||
public static Mat4f currentProjectionMatrix = new Mat4f();
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -168,8 +149,6 @@ public class NeoforgeClientProxy implements AbstractModInitializer.IEventProxy
|
|||||||
}
|
}
|
||||||
|
|
||||||
// executor to prevent locking up the render/event thread
|
// executor to prevent locking up the render/event thread
|
||||||
// if the getChunk() takes longer than expected
|
|
||||||
// (which can be caused by certain mods)
|
|
||||||
AbstractExecutorService executor = ThreadPoolUtil.getFileHandlerExecutor();
|
AbstractExecutorService executor = ThreadPoolUtil.getFileHandlerExecutor();
|
||||||
if (executor != null)
|
if (executor != null)
|
||||||
{
|
{
|
||||||
@@ -195,8 +174,6 @@ public class NeoforgeClientProxy implements AbstractModInitializer.IEventProxy
|
|||||||
}
|
}
|
||||||
|
|
||||||
// executor to prevent locking up the render/event thread
|
// executor to prevent locking up the render/event thread
|
||||||
// if the getChunk() takes longer than expected
|
|
||||||
// (which can be caused by certain mods)
|
|
||||||
AbstractExecutorService executor = ThreadPoolUtil.getFileHandlerExecutor();
|
AbstractExecutorService executor = ThreadPoolUtil.getFileHandlerExecutor();
|
||||||
if (executor != null)
|
if (executor != null)
|
||||||
{
|
{
|
||||||
@@ -244,16 +221,7 @@ public class NeoforgeClientProxy implements AbstractModInitializer.IEventProxy
|
|||||||
// rendering //
|
// rendering //
|
||||||
//===========//
|
//===========//
|
||||||
|
|
||||||
@SubscribeEvent
|
#if MC_VER < MC_1_21_6
|
||||||
public void beforeLevelRenderEvent(RenderLevelStageEvent event)
|
|
||||||
{
|
|
||||||
if (event.getStage() == RenderLevelStageEvent.Stage.AFTER_SKY)
|
|
||||||
{
|
|
||||||
currentModelViewMatrix = McObjectConverter.Convert(event.getModelViewMatrix());
|
|
||||||
currentProjectionMatrix = McObjectConverter.Convert(event.getProjectionMatrix());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
public void afterLevelRenderEvent(RenderLevelStageEvent event)
|
public void afterLevelRenderEvent(RenderLevelStageEvent event)
|
||||||
{
|
{
|
||||||
@@ -272,14 +240,62 @@ public class NeoforgeClientProxy implements AbstractModInitializer.IEventProxy
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
|
||||||
|
|
||||||
|
@SubscribeEvent
|
||||||
|
public void afterLevelEntityRenderEvent(RenderLevelStageEvent.AfterEntities event)
|
||||||
|
{
|
||||||
|
#if MC_VER < MC_1_21_9
|
||||||
|
ClientApi.RENDER_STATE.clientLevelWrapper = ClientLevelWrapper.getWrapperIfDifferent(ClientApi.RENDER_STATE.clientLevelWrapper, (ClientLevel)event.getLevel());
|
||||||
|
#else
|
||||||
|
ClientApi.RENDER_STATE.clientLevelWrapper = ClientLevelWrapper.getWrapperIfDifferent(ClientApi.RENDER_STATE.clientLevelWrapper, event.getLevelRenderer().level);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ClientApi.INSTANCE.renderFadeTransparent();
|
||||||
|
}
|
||||||
|
|
||||||
//================//
|
|
||||||
// helper methods //
|
|
||||||
//================//
|
|
||||||
|
|
||||||
private static LevelAccessor GetEventLevel(LevelEvent e) { return e.getLevel(); }
|
@SubscribeEvent
|
||||||
|
public void afterLevelTranslucentRenderEvent(RenderLevelStageEvent.AfterTranslucentBlocks event)
|
||||||
|
{
|
||||||
|
#if MC_VER < MC_1_21_9
|
||||||
|
ClientApi.RENDER_STATE.clientLevelWrapper = ClientLevelWrapper.getWrapperIfDifferent(ClientApi.RENDER_STATE.clientLevelWrapper, (ClientLevel)event.getLevel());
|
||||||
|
#else
|
||||||
|
ClientApi.RENDER_STATE.clientLevelWrapper = ClientLevelWrapper.getWrapperIfDifferent(ClientApi.RENDER_STATE.clientLevelWrapper, event.getLevelRenderer().level);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ClientApi.INSTANCE.renderDeferredLodsForShaders();
|
||||||
|
}
|
||||||
|
|
||||||
|
@SubscribeEvent
|
||||||
|
public void afterLevelRenderEvent(RenderLevelStageEvent.AfterLevel event)
|
||||||
|
{
|
||||||
|
#if MC_VER < MC_1_21_9
|
||||||
|
ClientApi.RENDER_STATE.clientLevelWrapper = ClientLevelWrapper.getWrapperIfDifferent(ClientApi.RENDER_STATE.clientLevelWrapper, (ClientLevel)event.getLevel());
|
||||||
|
#else
|
||||||
|
ClientApi.RENDER_STATE.clientLevelWrapper = ClientLevelWrapper.getWrapperIfDifferent(ClientApi.RENDER_STATE.clientLevelWrapper, event.getLevelRenderer().level);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// should generally only need to be set once per game session
|
||||||
|
// allows DH to render directly to Optifine's level frame buffer,
|
||||||
|
// allowing better shader support
|
||||||
|
MinecraftRenderWrapper.INSTANCE.finalLevelFrameBufferId = GL32.glGetInteger(GL32.GL_FRAMEBUFFER_BINDING);
|
||||||
|
}
|
||||||
|
catch (Exception | Error e)
|
||||||
|
{
|
||||||
|
LOGGER.error("Unexpected error in afterLevelRenderEvent: "+e.getMessage(), e);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ClientApi.INSTANCE.renderFadeOpaque();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,16 +22,18 @@ package com.seibel.distanthorizons.neoforge;
|
|||||||
import com.mojang.brigadier.CommandDispatcher;
|
import com.mojang.brigadier.CommandDispatcher;
|
||||||
import com.seibel.distanthorizons.common.AbstractModInitializer;
|
import com.seibel.distanthorizons.common.AbstractModInitializer;
|
||||||
import com.seibel.distanthorizons.common.wrappers.gui.GetConfigScreen;
|
import com.seibel.distanthorizons.common.wrappers.gui.GetConfigScreen;
|
||||||
|
import com.seibel.distanthorizons.common.wrappers.minecraft.MinecraftRenderWrapper;
|
||||||
import com.seibel.distanthorizons.core.api.internal.ClientApi;
|
import com.seibel.distanthorizons.core.api.internal.ClientApi;
|
||||||
import com.seibel.distanthorizons.core.config.Config;
|
|
||||||
import com.seibel.distanthorizons.core.api.internal.ServerApi;
|
import com.seibel.distanthorizons.core.api.internal.ServerApi;
|
||||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||||
import com.seibel.distanthorizons.core.network.messages.AbstractNetworkMessage;
|
import com.seibel.distanthorizons.core.network.messages.AbstractNetworkMessage;
|
||||||
|
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.misc.IPluginPacketSender;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.misc.IPluginPacketSender;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.misc.IServerPlayerWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.misc.IServerPlayerWrapper;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IModChecker;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IModChecker;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IOptifineAccessor;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IOptifineAccessor;
|
||||||
import com.seibel.distanthorizons.coreapi.ModInfo;
|
import com.seibel.distanthorizons.coreapi.ModInfo;
|
||||||
|
import com.seibel.distanthorizons.neoforge.wrappers.NeoforgeMinecraftRenderWrapper;
|
||||||
import com.seibel.distanthorizons.neoforge.wrappers.modAccessor.ModChecker;
|
import com.seibel.distanthorizons.neoforge.wrappers.modAccessor.ModChecker;
|
||||||
import com.seibel.distanthorizons.neoforge.wrappers.modAccessor.OptifineAccessor;
|
import com.seibel.distanthorizons.neoforge.wrappers.modAccessor.OptifineAccessor;
|
||||||
import net.minecraft.commands.CommandSourceStack;
|
import net.minecraft.commands.CommandSourceStack;
|
||||||
@@ -51,9 +53,13 @@ import java.util.function.Consumer;
|
|||||||
|
|
||||||
#if MC_VER < MC_1_20_6
|
#if MC_VER < MC_1_20_6
|
||||||
import net.neoforged.neoforge.client.ConfigScreenHandler;
|
import net.neoforged.neoforge.client.ConfigScreenHandler;
|
||||||
|
#elif MC_VER < MC_1_21_8
|
||||||
|
import net.neoforged.neoforge.client.gui.IConfigScreenFactory;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
#else
|
#else
|
||||||
import net.neoforged.neoforge.client.gui.IConfigScreenFactory;
|
import net.neoforged.neoforge.client.gui.IConfigScreenFactory;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import net.neoforged.neoforge.client.network.event.RegisterClientPayloadHandlersEvent;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -72,6 +78,11 @@ public class NeoforgeMain extends AbstractModInitializer
|
|||||||
{
|
{
|
||||||
this.onInitializeClient();
|
this.onInitializeClient();
|
||||||
eventBus.addListener(this::registerNetworkingClientServer);
|
eventBus.addListener(this::registerNetworkingClientServer);
|
||||||
|
|
||||||
|
#if MC_VER < MC_1_21_8
|
||||||
|
#else
|
||||||
|
eventBus.addListener(this::registerClientPayloadEvent);
|
||||||
|
#endif
|
||||||
});
|
});
|
||||||
|
|
||||||
// handles dedicated servers
|
// handles dedicated servers
|
||||||
@@ -99,6 +110,12 @@ public class NeoforgeMain extends AbstractModInitializer
|
|||||||
public void registerNetworkingServer(RegisterPayloadHandlersEvent event)
|
public void registerNetworkingServer(RegisterPayloadHandlersEvent event)
|
||||||
{ NeoforgePluginPacketSender.setPacketHandler(event, ServerApi.INSTANCE::pluginMessageReceived); }
|
{ NeoforgePluginPacketSender.setPacketHandler(event, ServerApi.INSTANCE::pluginMessageReceived); }
|
||||||
|
|
||||||
|
#if MC_VER < MC_1_21_8
|
||||||
|
#else
|
||||||
|
public void registerClientPayloadEvent(RegisterClientPayloadHandlersEvent event)
|
||||||
|
{ NeoforgePluginPacketSender.registerClientPacketHandler(event); }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -107,11 +124,18 @@ public class NeoforgeMain extends AbstractModInitializer
|
|||||||
protected IEventProxy createServerProxy(boolean isDedicated) { return new NeoforgeServerProxy(isDedicated); }
|
protected IEventProxy createServerProxy(boolean isDedicated) { return new NeoforgeServerProxy(isDedicated); }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void createInitialBindings()
|
protected void createInitialSharedBindings()
|
||||||
{
|
{
|
||||||
SingletonInjector.INSTANCE.bind(IModChecker.class, ModChecker.INSTANCE);
|
SingletonInjector.INSTANCE.bind(IModChecker.class, ModChecker.INSTANCE);
|
||||||
SingletonInjector.INSTANCE.bind(IPluginPacketSender.class, new NeoforgePluginPacketSender());
|
SingletonInjector.INSTANCE.bind(IPluginPacketSender.class, new NeoforgePluginPacketSender());
|
||||||
}
|
}
|
||||||
|
@Override
|
||||||
|
protected void createInitialClientBindings()
|
||||||
|
{
|
||||||
|
// replace MC RenderWrapper with more specific neoforge version
|
||||||
|
SingletonInjector.INSTANCE.unbind(IMinecraftRenderWrapper.class, MinecraftRenderWrapper.INSTANCE); // TODO replace with a replaceOrBind for simplicity
|
||||||
|
SingletonInjector.INSTANCE.bind(IMinecraftRenderWrapper.class, NeoforgeMinecraftRenderWrapper.INSTANCE);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected IEventProxy createClientProxy() { return new NeoforgeClientProxy(); }
|
protected IEventProxy createClientProxy() { return new NeoforgeClientProxy(); }
|
||||||
@@ -141,7 +165,9 @@ public class NeoforgeMain extends AbstractModInitializer
|
|||||||
@Override
|
@Override
|
||||||
protected void subscribeClientStartedEvent(Runnable eventHandler)
|
protected void subscribeClientStartedEvent(Runnable eventHandler)
|
||||||
{
|
{
|
||||||
// FIXME What event is this?
|
// Just run the event handler, since there are no proper ClientLifecycleEvent for the client
|
||||||
|
// to signify readiness other than FmlClientSetupEvent
|
||||||
|
eventHandler.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
+32
-1
@@ -14,10 +14,19 @@ import java.util.Optional;
|
|||||||
import java.util.function.BiConsumer;
|
import java.util.function.BiConsumer;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
#if MC_VER < MC_1_21_8
|
||||||
|
#else
|
||||||
|
import net.neoforged.neoforge.client.network.ClientPacketDistributor;
|
||||||
|
import net.neoforged.neoforge.client.network.event.RegisterClientPayloadHandlersEvent;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
public class NeoforgePluginPacketSender extends AbstractPluginPacketSender
|
public class NeoforgePluginPacketSender extends AbstractPluginPacketSender
|
||||||
{
|
{
|
||||||
private static BiConsumer<IServerPlayerWrapper, AbstractNetworkMessage> packetConsumer;
|
private static BiConsumer<IServerPlayerWrapper, AbstractNetworkMessage> packetConsumer;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static void setPacketHandler(RegisterPayloadHandlersEvent event, Consumer<AbstractNetworkMessage> consumer)
|
public static void setPacketHandler(RegisterPayloadHandlersEvent event, Consumer<AbstractNetworkMessage> consumer)
|
||||||
{ setPacketHandler(event, (player, buffer) -> consumer.accept(buffer)); }
|
{ setPacketHandler(event, (player, buffer) -> consumer.accept(buffer)); }
|
||||||
public static void setPacketHandler(RegisterPayloadHandlersEvent event, BiConsumer<IServerPlayerWrapper, AbstractNetworkMessage> consumer)
|
public static void setPacketHandler(RegisterPayloadHandlersEvent event, BiConsumer<IServerPlayerWrapper, AbstractNetworkMessage> consumer)
|
||||||
@@ -39,9 +48,31 @@ public class NeoforgePluginPacketSender extends AbstractPluginPacketSender
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if MC_VER < MC_1_21_8
|
||||||
|
#else
|
||||||
|
public static void registerClientPacketHandler(RegisterClientPayloadHandlersEvent event)
|
||||||
|
{
|
||||||
|
// as of MC 1.21.7 Neo added a separate client network register
|
||||||
|
// https://github.com/neoforged/NeoForge/pull/2272
|
||||||
|
event.register(CommonPacketPayload.TYPE, (payload, context) ->
|
||||||
|
{
|
||||||
|
if (payload.message() != null)
|
||||||
|
{
|
||||||
|
packetConsumer.accept(null, payload.message());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendToServer(AbstractNetworkMessage message)
|
public void sendToServer(AbstractNetworkMessage message)
|
||||||
{ PacketDistributor.sendToServer(new CommonPacketPayload(message)); }
|
{
|
||||||
|
#if MC_VER < MC_1_21_8
|
||||||
|
PacketDistributor.sendToServer(new CommonPacketPayload(message));
|
||||||
|
#else
|
||||||
|
ClientPacketDistributor.sendToServer(new CommonPacketPayload(message));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendToClient(ServerPlayer serverPlayer, AbstractNetworkMessage message)
|
public void sendToClient(ServerPlayer serverPlayer, AbstractNetworkMessage message)
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ import net.neoforged.bus.api.SubscribeEvent;
|
|||||||
import net.neoforged.neoforge.event.server.ServerAboutToStartEvent;
|
import net.neoforged.neoforge.event.server.ServerAboutToStartEvent;
|
||||||
import net.neoforged.neoforge.event.server.ServerStoppingEvent;
|
import net.neoforged.neoforge.event.server.ServerStoppingEvent;
|
||||||
|
|
||||||
import org.apache.logging.log4j.Logger;
|
import com.seibel.distanthorizons.core.logging.DhLogger;
|
||||||
|
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
@@ -40,7 +40,7 @@ public class NeoforgeServerProxy implements AbstractModInitializer.IEventProxy
|
|||||||
private static LevelAccessor GetEventLevel(LevelEvent e) { return e.getLevel(); }
|
private static LevelAccessor GetEventLevel(LevelEvent e) { return e.getLevel(); }
|
||||||
|
|
||||||
private final ServerApi serverApi = ServerApi.INSTANCE;
|
private final ServerApi serverApi = ServerApi.INSTANCE;
|
||||||
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
|
private static final DhLogger LOGGER = new DhLoggerBuilder().build();
|
||||||
private final boolean isDedicated;
|
private final boolean isDedicated;
|
||||||
public static Supplier<Boolean> isGenerationThreadChecker = null;
|
public static Supplier<Boolean> isGenerationThreadChecker = null;
|
||||||
|
|
||||||
@@ -152,8 +152,12 @@ public class NeoforgeServerProxy implements AbstractModInitializer.IEventProxy
|
|||||||
private static ServerLevelWrapper getServerLevelWrapper(ServerLevel level) { return ServerLevelWrapper.getWrapper(level); }
|
private static ServerLevelWrapper getServerLevelWrapper(ServerLevel level) { return ServerLevelWrapper.getWrapper(level); }
|
||||||
private static ServerLevelWrapper getServerLevelWrapper(ResourceKey<Level> resourceKey, PlayerEvent event)
|
private static ServerLevelWrapper getServerLevelWrapper(ResourceKey<Level> resourceKey, PlayerEvent event)
|
||||||
{
|
{
|
||||||
|
#if MC_VER < MC_1_21_9
|
||||||
//noinspection DataFlowIssue (possible NPE after getServer())
|
//noinspection DataFlowIssue (possible NPE after getServer())
|
||||||
return getServerLevelWrapper(event.getEntity().getServer().getLevel(resourceKey));
|
return getServerLevelWrapper(event.getEntity().getServer().getLevel(resourceKey));
|
||||||
|
#else
|
||||||
|
return getServerLevelWrapper(event.getEntity().level().getServer().getLevel(resourceKey));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ServerPlayerWrapper getServerPlayerWrapper(PlayerEvent event) { return ServerPlayerWrapper.getWrapper((ServerPlayer) event.getEntity()); }
|
private static ServerPlayerWrapper getServerPlayerWrapper(PlayerEvent event) { return ServerPlayerWrapper.getWrapper((ServerPlayer) event.getEntity()); }
|
||||||
|
|||||||
+9
@@ -1,5 +1,6 @@
|
|||||||
package com.seibel.distanthorizons.neoforge.mixins.client;
|
package com.seibel.distanthorizons.neoforge.mixins.client;
|
||||||
|
|
||||||
|
#if MC_VER < MC_1_21_9
|
||||||
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;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
@@ -8,16 +9,24 @@ import org.spongepowered.asm.mixin.injection.Inject;
|
|||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
#else
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import net.minecraft.client.gui.components.DebugScreenOverlay;
|
||||||
|
#endif
|
||||||
|
|
||||||
@Mixin(DebugScreenOverlay.class)
|
@Mixin(DebugScreenOverlay.class)
|
||||||
public class MixinDebugScreenOverlay
|
public class MixinDebugScreenOverlay
|
||||||
{
|
{
|
||||||
|
|
||||||
|
#if MC_VER < MC_1_21_9
|
||||||
@Inject(method = "getSystemInformation", at = @At("RETURN"))
|
@Inject(method = "getSystemInformation", at = @At("RETURN"))
|
||||||
private void addCustomF3(CallbackInfoReturnable<List<String>> cir)
|
private void addCustomF3(CallbackInfoReturnable<List<String>> cir)
|
||||||
{
|
{
|
||||||
List<String> messages = cir.getReturnValue();
|
List<String> messages = cir.getReturnValue();
|
||||||
F3Screen.addStringToDisplay(messages);
|
F3Screen.addStringToDisplay(messages);
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
// handled by DhDebugScreenEntry for MC versions after 1.21.10
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+117
-31
@@ -22,67 +22,87 @@ package com.seibel.distanthorizons.neoforge.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;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Unique;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
|
||||||
|
|
||||||
import com.mojang.blaze3d.systems.RenderSystem;
|
|
||||||
|
|
||||||
import net.minecraft.client.Camera;
|
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.effect.MobEffects;
|
||||||
import net.minecraft.world.entity.Entity;
|
import net.minecraft.world.entity.Entity;
|
||||||
import net.minecraft.world.entity.LivingEntity;
|
import net.minecraft.world.entity.LivingEntity;
|
||||||
|
|
||||||
#if MC_VER < MC_1_17_1
|
#if MC_VER < MC_1_17_1
|
||||||
import net.minecraft.world.level.material.FluidState;
|
import net.minecraft.world.level.material.FluidState;
|
||||||
org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
import net.minecraft.client.renderer.FogRenderer;
|
||||||
|
import net.minecraft.client.renderer.FogRenderer.FogMode;
|
||||||
|
import com.mojang.blaze3d.systems.RenderSystem;
|
||||||
|
|
||||||
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
#elif MC_VER < MC_1_21_3
|
#elif MC_VER < MC_1_21_3
|
||||||
import net.minecraft.world.level.material.FogType;
|
import net.minecraft.world.level.material.FogType;
|
||||||
|
import net.minecraft.client.renderer.FogRenderer;
|
||||||
|
import net.minecraft.client.renderer.FogRenderer.FogMode;
|
||||||
|
import com.mojang.blaze3d.systems.RenderSystem;
|
||||||
|
|
||||||
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
#elif MC_VER < MC_1_21_6
|
||||||
|
import net.minecraft.world.level.material.FogType;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||||
|
import com.mojang.blaze3d.shaders.FogShape;
|
||||||
|
import net.minecraft.client.renderer.FogRenderer;
|
||||||
|
import net.minecraft.client.renderer.FogRenderer.FogMode;
|
||||||
|
import net.minecraft.client.renderer.FogParameters;
|
||||||
|
import org.joml.Vector4f;
|
||||||
|
import com.mojang.blaze3d.systems.RenderSystem;
|
||||||
|
|
||||||
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
#else
|
#else
|
||||||
import net.minecraft.client.renderer.FogParameters;
|
|
||||||
import net.minecraft.world.level.material.FogType;
|
import net.minecraft.world.level.material.FogType;
|
||||||
import org.joml.Vector4f;
|
import net.minecraft.client.renderer.fog.FogRenderer;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
import net.minecraft.client.renderer.fog.FogData;
|
||||||
|
|
||||||
|
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
|
||||||
|
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Mixin(FogRenderer.class)
|
@Mixin(FogRenderer.class)
|
||||||
public class MixinFogRenderer
|
public class MixinFogRenderer
|
||||||
{
|
{
|
||||||
// Using this instead of Float.MAX_VALUE because Sodium don't like it.
|
// Using this instead of Float.MAX_VALUE because Sodium don't like it.
|
||||||
|
@Unique
|
||||||
private static final float A_REALLY_REALLY_BIG_VALUE = 420694206942069.F;
|
private static final float A_REALLY_REALLY_BIG_VALUE = 420694206942069.F;
|
||||||
|
@Unique
|
||||||
private static final float A_EVEN_LARGER_VALUE = 42069420694206942069.F;
|
private static final float A_EVEN_LARGER_VALUE = 42069420694206942069.F;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#if MC_VER == MC_1_17_1 || MC_VER == MC_1_18_2
|
#if MC_VER < MC_1_19_2
|
||||||
@Inject(at = @At("RETURN"),
|
@Inject(at = @At("RETURN"), method = "setupFog")
|
||||||
method = "setupFog(Lnet/minecraft/client/Camera;Lnet/minecraft/client/renderer/FogRenderer$FogMode;FZF)V",
|
private static void disableSetupFog(Camera camera, FogMode fogMode, float f, boolean bl, CallbackInfo callback)
|
||||||
remap = false)
|
|
||||||
private static void disableSetupFog(Camera camera, FogMode fogMode, float f, boolean bl, float partTick, CallbackInfo callback)
|
|
||||||
#elif MC_VER < MC_1_21_3
|
#elif MC_VER < MC_1_21_3
|
||||||
@Inject(at = @At("RETURN"),
|
@Inject(at = @At("RETURN"), method = "setupFog")
|
||||||
method = "setupFog(Lnet/minecraft/client/Camera;Lnet/minecraft/client/renderer/FogRenderer$FogMode;FZF)V",
|
private static void disableSetupFog(Camera camera, FogMode fogMode, float f, boolean bl, float g, CallbackInfo callback)
|
||||||
remap = true)
|
#elif MC_VER < MC_1_21_6
|
||||||
private static void disableSetupFog(Camera camera, FogMode fogMode, float f, boolean bl, float partTick, CallbackInfo callback)
|
@Inject(at = @At("RETURN"), method = "setupFog", cancellable = true)
|
||||||
|
private static void disableSetupFog(Camera camera, FogMode fogMode, Vector4f vector4f, float f, boolean bl, float g, CallbackInfoReturnable<FogParameters> callback)
|
||||||
#else
|
#else
|
||||||
@Inject(at = @At("RETURN"),
|
@Unique
|
||||||
method = "setupFog(Lnet/minecraft/client/Camera;Lnet/minecraft/client/renderer/FogRenderer$FogMode;Lorg/joml/Vector4f;FZF)Lnet/minecraft/client/renderer/FogParameters;",
|
private static void unused()
|
||||||
remap = true, cancellable = true)
|
|
||||||
private static void disableSetupFog(Camera camera, FogMode fogMode, Vector4f vector4f, float f, boolean bl, float partTick, CallbackInfoReturnable<FogParameters> callback)
|
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
boolean cameraNotInFluid = cameraNotInFluid(camera);
|
#if MC_VER < MC_1_21_6
|
||||||
|
boolean cancelFog = cancelFog(camera, fogMode);
|
||||||
|
#elif MC_VER < MC_1_21_6
|
||||||
|
boolean cancelFog = cancelFog(camera);
|
||||||
|
#else
|
||||||
|
boolean cancelFog = cancelFog();
|
||||||
|
#endif
|
||||||
|
|
||||||
Entity entity = camera.getEntity();
|
if (cancelFog)
|
||||||
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.enableVanillaFog.get())
|
|
||||||
{
|
{
|
||||||
#if MC_VER < MC_1_17_1
|
#if MC_VER < MC_1_17_1
|
||||||
RenderSystem.fogStart(A_REALLY_REALLY_BIG_VALUE);
|
RenderSystem.fogStart(A_REALLY_REALLY_BIG_VALUE);
|
||||||
@@ -90,12 +110,77 @@ public class MixinFogRenderer
|
|||||||
#elif MC_VER < MC_1_21_3
|
#elif MC_VER < MC_1_21_3
|
||||||
RenderSystem.setShaderFogStart(A_REALLY_REALLY_BIG_VALUE);
|
RenderSystem.setShaderFogStart(A_REALLY_REALLY_BIG_VALUE);
|
||||||
RenderSystem.setShaderFogEnd(A_EVEN_LARGER_VALUE);
|
RenderSystem.setShaderFogEnd(A_EVEN_LARGER_VALUE);
|
||||||
#else
|
#elif MC_VER < MC_1_21_6
|
||||||
callback.setReturnValue(FogParameters.NO_FOG);
|
callback.setReturnValue(FogParameters.NO_FOG);
|
||||||
|
#else
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if MC_VER < MC_1_21_6
|
||||||
|
#else
|
||||||
|
|
||||||
|
// In MC's FogRenderer they clamp the "renderDistanceEnd" fog field to the render distance,
|
||||||
|
// which prevents us from disabling the vanilla fog.
|
||||||
|
// This mixin fires after they set the "renderDistanceEnd" so we can change it.
|
||||||
|
@WrapOperation(
|
||||||
|
method = "setupFog",
|
||||||
|
at = @At(
|
||||||
|
value = "FIELD",
|
||||||
|
target = "Lnet/minecraft/client/renderer/fog/FogData;renderDistanceEnd:F",
|
||||||
|
opcode = org.objectweb.asm.Opcodes.PUTFIELD
|
||||||
|
)
|
||||||
|
)
|
||||||
|
private void onSetRenderDistanceEnd(FogData instance, float value, Operation<Void> original)
|
||||||
|
{
|
||||||
|
if (cancelFog())
|
||||||
|
{
|
||||||
|
instance.environmentalStart = A_REALLY_REALLY_BIG_VALUE;
|
||||||
|
instance.environmentalEnd = A_EVEN_LARGER_VALUE;
|
||||||
|
|
||||||
|
instance.renderDistanceStart = A_REALLY_REALLY_BIG_VALUE;
|
||||||
|
instance.renderDistanceEnd = A_EVEN_LARGER_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Always call the original with the modified or original value
|
||||||
|
original.call(instance, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
@Unique
|
||||||
|
#if MC_VER < MC_1_21_6
|
||||||
|
private static boolean cancelFog(Camera camera, FogMode fogMode)
|
||||||
|
#else
|
||||||
|
private static boolean cancelFog()
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
#if MC_VER < MC_1_21_6
|
||||||
|
Entity entity = camera.getEntity();
|
||||||
|
#else
|
||||||
|
Camera camera = Minecraft.getInstance().gameRenderer.getMainCamera();
|
||||||
|
Entity entity = camera.getEntity();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
boolean cameraNotInFluid = cameraNotInFluid(camera);
|
||||||
|
boolean isSpecialFog = (entity instanceof LivingEntity) && ((LivingEntity) entity).hasEffect(MobEffects.BLINDNESS);
|
||||||
|
|
||||||
|
boolean cancelFog = !isSpecialFog;
|
||||||
|
cancelFog = cancelFog && cameraNotInFluid;
|
||||||
|
#if MC_VER < MC_1_21_6
|
||||||
|
cancelFog = cancelFog && (fogMode == FogMode.FOG_TERRAIN);
|
||||||
|
#endif
|
||||||
|
cancelFog = cancelFog && !SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class).isFogStateSpecial();
|
||||||
|
cancelFog = cancelFog && !Config.Client.Advanced.Graphics.Fog.enableVanillaFog.get();
|
||||||
|
|
||||||
|
return cancelFog;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Unique
|
||||||
private static boolean cameraNotInFluid(Camera camera)
|
private static boolean cameraNotInFluid(Camera camera)
|
||||||
{
|
{
|
||||||
#if MC_VER < MC_1_17_1
|
#if MC_VER < MC_1_17_1
|
||||||
@@ -110,4 +195,5 @@ public class MixinFogRenderer
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+108
-99
@@ -19,48 +19,53 @@
|
|||||||
|
|
||||||
package com.seibel.distanthorizons.neoforge.mixins.client;
|
package com.seibel.distanthorizons.neoforge.mixins.client;
|
||||||
|
|
||||||
import com.mojang.blaze3d.systems.RenderSystem;
|
#if MC_VER < MC_1_21_6
|
||||||
import com.mojang.blaze3d.vertex.PoseStack;
|
|
||||||
#if MC_VER < MC_1_19_4
|
|
||||||
import com.mojang.math.Matrix4f;
|
|
||||||
#else
|
|
||||||
import com.seibel.distanthorizons.core.util.math.Mat4f;
|
|
||||||
import com.seibel.distanthorizons.neoforge.NeoforgeClientProxy;
|
|
||||||
import net.minecraft.client.Camera;
|
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.renderer.GameRenderer;
|
|
||||||
import net.minecraft.client.renderer.LightTexture;
|
|
||||||
import org.joml.Matrix4f;
|
|
||||||
#endif
|
|
||||||
import com.seibel.distanthorizons.common.wrappers.McObjectConverter;
|
|
||||||
import com.seibel.distanthorizons.common.wrappers.chunk.ChunkWrapper;
|
|
||||||
import com.seibel.distanthorizons.common.wrappers.world.ClientLevelWrapper;
|
|
||||||
import com.seibel.distanthorizons.core.config.Config;
|
|
||||||
import com.seibel.distanthorizons.core.api.internal.ClientApi;
|
|
||||||
import net.minecraft.client.multiplayer.ClientLevel;
|
import net.minecraft.client.multiplayer.ClientLevel;
|
||||||
import net.minecraft.client.renderer.LevelRenderer;
|
import net.minecraft.client.renderer.LevelRenderer;
|
||||||
import net.minecraft.client.renderer.RenderType;
|
import net.minecraft.client.renderer.RenderType;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import net.neoforged.neoforge.client.event.RenderLevelStageEvent;
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
import org.joml.Matrix4f;
|
||||||
import org.spongepowered.asm.mixin.Unique;
|
#else
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import com.mojang.blaze3d.vertex.PoseStack;
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
import net.minecraft.client.Minecraft;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
import net.minecraft.client.renderer.MultiBufferSource;
|
||||||
|
import net.minecraft.client.renderer.chunk.ChunkSectionsToRender;
|
||||||
|
import net.minecraft.client.Camera;
|
||||||
|
import net.minecraft.client.DeltaTracker;
|
||||||
|
import net.minecraft.client.multiplayer.ClientLevel;
|
||||||
|
import net.minecraft.client.renderer.LevelRenderer;
|
||||||
|
|
||||||
#if MC_VER < MC_1_17_1
|
import org.joml.Matrix4f;
|
||||||
import org.lwjgl.opengl.GL15;
|
import org.joml.Matrix4fc;
|
||||||
|
import org.joml.Vector4f;
|
||||||
|
|
||||||
|
import com.mojang.blaze3d.buffers.GpuBufferSlice;
|
||||||
|
import com.mojang.blaze3d.resource.GraphicsResourceAllocator;
|
||||||
|
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This class is used to mix in DH's rendering code
|
import com.seibel.distanthorizons.core.logging.DhLogger;
|
||||||
* before Minecraft starts rendering blocks.
|
|
||||||
* If this wasn't done, and we used Forge's
|
import com.seibel.distanthorizons.neoforge.NeoforgeClientProxy;
|
||||||
* render last event, the LODs would render on top
|
import com.seibel.distanthorizons.common.wrappers.McObjectConverter;
|
||||||
* of the normal terrain. <br><br>
|
import com.seibel.distanthorizons.common.wrappers.world.ClientLevelWrapper;
|
||||||
*
|
import com.seibel.distanthorizons.core.api.internal.ClientApi;
|
||||||
* This is also the mixin for rendering the clouds
|
import com.seibel.distanthorizons.core.config.Config;
|
||||||
*/
|
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||||
|
import com.seibel.distanthorizons.core.util.math.Mat4f;
|
||||||
|
import com.seibel.distanthorizons.coreapi.ModInfo;
|
||||||
|
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
|
import org.spongepowered.asm.mixin.Unique;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
@Mixin(LevelRenderer.class)
|
@Mixin(LevelRenderer.class)
|
||||||
public class MixinLevelRenderer
|
public class MixinLevelRenderer
|
||||||
{
|
{
|
||||||
@@ -70,73 +75,67 @@ public class MixinLevelRenderer
|
|||||||
#endif
|
#endif
|
||||||
private ClientLevel level;
|
private ClientLevel level;
|
||||||
|
|
||||||
|
@Unique
|
||||||
|
private static final DhLogger LOGGER = new DhLoggerBuilder().build();
|
||||||
|
|
||||||
#if MC_VER < MC_1_17_1
|
|
||||||
@Inject(at = @At("HEAD"),
|
|
||||||
method = "renderChunkLayer(Lnet/minecraft/client/renderer/RenderType;Lcom/mojang/blaze3d/vertex/PoseStack;DDD)V",
|
#if MC_VER < MC_1_21_6
|
||||||
cancellable = true)
|
@Inject(at = @At("HEAD"), method = "renderSectionLayer")
|
||||||
private void renderChunkLayer(RenderType renderType, PoseStack matrixStackIn, double xIn, double yIn, double zIn, CallbackInfo callback)
|
private void renderChunkLayer(RenderType renderType, double x, double y, double z, Matrix4f modelViewMatrix, Matrix4f projectionMatrix, CallbackInfo callback)
|
||||||
#elif MC_VER < MC_1_19_4
|
#elif MC_VER < MC_1_21_9
|
||||||
@Inject(at = @At("HEAD"),
|
@Inject(at = @At("HEAD"), method = "renderLevel")
|
||||||
method = "renderChunkLayer(Lnet/minecraft/client/renderer/RenderType;Lcom/mojang/blaze3d/vertex/PoseStack;DDDLcom/mojang/math/Matrix4f;)V",
|
private void onRenderLevel(
|
||||||
cancellable = true)
|
GraphicsResourceAllocator resourceAllocator, DeltaTracker deltaTracker,
|
||||||
private void renderChunkLayer(RenderType renderType, PoseStack modelViewMatrixStack, double cameraXBlockPos, double cameraYBlockPos, double cameraZBlockPos, Matrix4f projectionMatrix, CallbackInfo callback)
|
boolean renderBlockOutline, Camera camera,
|
||||||
#elif MC_VER < MC_1_20_2
|
Matrix4f positionMatrix, Matrix4f projectionMatrix, GpuBufferSlice gpuBufferSlice,
|
||||||
@Inject(at = @At("HEAD"),
|
Vector4f skyColor, boolean thinFog, CallbackInfo callback)
|
||||||
method = "renderChunkLayer(Lnet/minecraft/client/renderer/RenderType;Lcom/mojang/blaze3d/vertex/PoseStack;DDDLorg/joml/Matrix4f;)V",
|
|
||||||
cancellable = true)
|
|
||||||
private void renderChunkLayer(RenderType renderType, PoseStack modelViewMatrixStack, double cameraXBlockPos, double cameraYBlockPos, double cameraZBlockPos, Matrix4f projectionMatrix, CallbackInfo callback)
|
|
||||||
#elif MC_VER < MC_1_20_6
|
|
||||||
@Inject(at = @At("HEAD"),
|
|
||||||
method = "Lnet/minecraft/client/renderer/LevelRenderer;renderSectionLayer(Lnet/minecraft/client/renderer/RenderType;Lcom/mojang/blaze3d/vertex/PoseStack;DDDLorg/joml/Matrix4f;)V",
|
|
||||||
cancellable = true)
|
|
||||||
private void renderChunkLayer(RenderType renderType, PoseStack modelViewMatrixStack, double camX, double camY, double camZ, Matrix4f projectionMatrix, CallbackInfo callback)
|
|
||||||
#else
|
#else
|
||||||
@Inject(at = @At("HEAD"),
|
@Inject(at = @At("HEAD"), method = "renderLevel")
|
||||||
method = "Lnet/minecraft/client/renderer/LevelRenderer;renderSectionLayer(Lnet/minecraft/client/renderer/RenderType;DDDLorg/joml/Matrix4f;Lorg/joml/Matrix4f;)V",
|
private void renderLevel(
|
||||||
cancellable = true)
|
GraphicsResourceAllocator resourceAllocator, DeltaTracker deltaTracker,
|
||||||
private void renderChunkLayer(RenderType renderType, double x, double y, double z, Matrix4f projectionMatrix, Matrix4f frustumMatrix, CallbackInfo callback)
|
boolean renderBlockOutline, Camera camera,
|
||||||
#endif
|
Matrix4f positionMatrix, Matrix4f projectionMatrix, Matrix4f idkMatrix, GpuBufferSlice gpuBufferSlice,
|
||||||
|
Vector4f skyColor, boolean thinFog, CallbackInfo callback)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
#if MC_VER == MC_1_16_5
|
#if MC_VER < MC_1_21_6
|
||||||
// get the matrices from the OpenGL fixed pipeline
|
// MC combined the model view and projection matricies
|
||||||
float[] mcProjMatrixRaw = new float[16];
|
ClientApi.RENDER_STATE.mcModelViewMatrix = McObjectConverter.Convert(modelViewMatrix);
|
||||||
GL15.glGetFloatv(GL15.GL_PROJECTION_MATRIX, mcProjMatrixRaw);
|
ClientApi.RENDER_STATE.mcProjectionMatrix = McObjectConverter.Convert(projectionMatrix);
|
||||||
Mat4f mcProjectionMatrix = new Mat4f(mcProjMatrixRaw);
|
|
||||||
mcProjectionMatrix.transpose();
|
|
||||||
|
|
||||||
Mat4f mcModelViewMatrix = McObjectConverter.Convert(matrixStackIn.last().pose());
|
|
||||||
|
|
||||||
#elif MC_VER <= MC_1_20_4
|
|
||||||
// get the matrices directly from MC
|
|
||||||
Mat4f mcModelViewMatrix = McObjectConverter.Convert(modelViewMatrixStack.last().pose());
|
|
||||||
Mat4f mcProjectionMatrix = McObjectConverter.Convert(projectionMatrix);
|
|
||||||
#else
|
#else
|
||||||
// get the matrices from neoForge's render event.
|
ClientApi.RENDER_STATE.mcProjectionMatrix = McObjectConverter.Convert(projectionMatrix);
|
||||||
// We can't call the renderer there because we don't have access to the level that's being rendered
|
|
||||||
Mat4f mcModelViewMatrix = NeoforgeClientProxy.currentModelViewMatrix;
|
|
||||||
Mat4f mcProjectionMatrix = NeoforgeClientProxy.currentProjectionMatrix;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
float frameTime;
|
|
||||||
#if MC_VER < MC_1_21_1
|
#if MC_VER < MC_1_21_1
|
||||||
frameTime = Minecraft.getInstance().getFrameTime();
|
ClientApi.RENDER_STATE.frameTime = Minecraft.getInstance().getFrameTime();
|
||||||
#elif MC_VER < MC_1_21_3
|
#elif MC_VER < MC_1_21_3
|
||||||
frameTime = Minecraft.getInstance().getTimer().getRealtimeDeltaTicks();
|
ClientApi.RENDER_STATE.frameTime = Minecraft.getInstance().getTimer().getRealtimeDeltaTicks();
|
||||||
#else
|
#else
|
||||||
frameTime = Minecraft.getInstance().deltaTracker.getRealtimeDeltaTicks();
|
ClientApi.RENDER_STATE.frameTime = Minecraft.getInstance().deltaTracker.getRealtimeDeltaTicks();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
ClientApi.RENDER_STATE.clientLevelWrapper = ClientLevelWrapper.getWrapperIfDifferent(ClientApi.RENDER_STATE.clientLevelWrapper, this.level);
|
||||||
|
|
||||||
|
|
||||||
|
#if MC_VER < MC_1_21_6
|
||||||
|
|
||||||
|
// only crash during development
|
||||||
|
if (ModInfo.IS_DEV_BUILD)
|
||||||
|
{
|
||||||
|
ClientApi.RENDER_STATE.canRenderOrThrow();
|
||||||
|
}
|
||||||
|
|
||||||
// render LODs
|
// render LODs
|
||||||
if (renderType.equals(RenderType.solid()))
|
if (renderType.equals(RenderType.solid()))
|
||||||
{
|
{
|
||||||
ClientApi.INSTANCE.renderLods(ClientLevelWrapper.getWrapper(this.level), mcModelViewMatrix, mcProjectionMatrix, frameTime);
|
ClientApi.INSTANCE.renderLods();
|
||||||
}
|
}
|
||||||
else if (renderType.equals(RenderType.translucent()))
|
else if (renderType.equals(RenderType.translucent()))
|
||||||
{
|
{
|
||||||
ClientApi.INSTANCE.renderDeferredLods(ClientLevelWrapper.getWrapper(this.level), mcModelViewMatrix, mcProjectionMatrix, frameTime);
|
ClientApi.INSTANCE.renderDeferredLodsForShaders();
|
||||||
}
|
}
|
||||||
|
|
||||||
// render fade
|
// render fade
|
||||||
@@ -145,28 +144,38 @@ public class MixinLevelRenderer
|
|||||||
// we need to trigger for the renderType after those passes are done
|
// we need to trigger for the renderType after those passes are done
|
||||||
if (renderType.equals(RenderType.cutout()))
|
if (renderType.equals(RenderType.cutout()))
|
||||||
{
|
{
|
||||||
ClientApi.INSTANCE.renderFadeOpaque(
|
ClientApi.INSTANCE.renderFadeOpaque();
|
||||||
mcModelViewMatrix,
|
|
||||||
mcProjectionMatrix,
|
|
||||||
frameTime,
|
|
||||||
ClientLevelWrapper.getWrapper(this.level)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
else if (renderType.equals(RenderType.tripwire()))
|
else if (renderType.equals(RenderType.tripwire()))
|
||||||
{
|
{
|
||||||
ClientApi.INSTANCE.renderFade(
|
ClientApi.INSTANCE.renderFadeTransparent();
|
||||||
mcModelViewMatrix,
|
|
||||||
mcProjectionMatrix,
|
|
||||||
frameTime,
|
|
||||||
ClientLevelWrapper.getWrapper(this.level)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Config.Client.Advanced.Debugging.lodOnlyMode.get())
|
|
||||||
{
|
|
||||||
callback.cancel();
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if MC_VER < MC_1_21_6
|
||||||
|
|
||||||
|
// formerly handled in renderChunkLayer()
|
||||||
|
|
||||||
|
#else
|
||||||
|
@Inject(at = @At("HEAD"), method = "prepareChunkRenders")
|
||||||
|
private void renderChunkLayer(Matrix4fc modelViewMatrix, double d, double e, double f, CallbackInfoReturnable<ChunkSectionsToRender> callback)
|
||||||
|
{
|
||||||
|
ClientApi.RENDER_STATE.mcModelViewMatrix = McObjectConverter.Convert(modelViewMatrix);
|
||||||
|
ClientApi.RENDER_STATE.clientLevelWrapper = ClientLevelWrapper.getWrapperIfDifferent(ClientApi.RENDER_STATE.clientLevelWrapper, this.level);
|
||||||
|
|
||||||
|
// only crash during development
|
||||||
|
if (ModInfo.IS_DEV_BUILD)
|
||||||
|
{
|
||||||
|
ClientApi.RENDER_STATE.canRenderOrThrow();
|
||||||
|
}
|
||||||
|
|
||||||
|
ClientApi.INSTANCE.renderLods();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+39
-23
@@ -19,17 +19,14 @@
|
|||||||
|
|
||||||
package com.seibel.distanthorizons.neoforge.mixins.client;
|
package com.seibel.distanthorizons.neoforge.mixins.client;
|
||||||
|
|
||||||
|
|
||||||
import com.mojang.blaze3d.pipeline.TextureTarget;
|
|
||||||
import com.mojang.blaze3d.platform.NativeImage;
|
|
||||||
|
|
||||||
import com.seibel.distanthorizons.common.wrappers.minecraft.MinecraftRenderWrapper;
|
import com.seibel.distanthorizons.common.wrappers.minecraft.MinecraftRenderWrapper;
|
||||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
|
||||||
|
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
|
||||||
|
import com.seibel.distanthorizons.neoforge.wrappers.NeoforgeTextureUnwrapper;
|
||||||
import net.minecraft.client.renderer.LightTexture;
|
import net.minecraft.client.renderer.LightTexture;
|
||||||
|
|
||||||
import org.lwjgl.opengl.GL32;
|
|
||||||
import org.spongepowered.asm.mixin.Final;
|
import org.spongepowered.asm.mixin.Final;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
@@ -37,30 +34,37 @@ import org.spongepowered.asm.mixin.injection.At;
|
|||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
|
#if MC_VER < MC_1_21_3
|
||||||
|
import com.mojang.blaze3d.platform.NativeImage;
|
||||||
|
#elif MC_VER < MC_1_21_5
|
||||||
|
import com.mojang.blaze3d.pipeline.TextureTarget;
|
||||||
|
#elif MC_VER < MC_1_21_9
|
||||||
|
import com.mojang.blaze3d.opengl.GlTexture;
|
||||||
|
import com.mojang.blaze3d.systems.RenderSystem;
|
||||||
|
import com.mojang.blaze3d.textures.GpuTexture;
|
||||||
|
#else
|
||||||
|
import net.neoforged.neoforge.client.blaze3d.validation.ValidationGpuTexture;
|
||||||
|
import com.mojang.blaze3d.opengl.GlTexture;
|
||||||
|
import com.mojang.blaze3d.textures.GpuTexture;
|
||||||
|
#endif
|
||||||
|
|
||||||
@Mixin(LightTexture.class)
|
@Mixin(LightTexture.class)
|
||||||
public class MixinLightTexture
|
public class MixinLightTexture
|
||||||
{
|
{
|
||||||
#if MC_VER < MC_1_21_3
|
#if MC_VER < MC_1_21_3
|
||||||
@Shadow
|
@Shadow
|
||||||
@Final
|
@Final
|
||||||
private NativeImage lightPixels;
|
private NativeImage lightPixels;
|
||||||
|
#elif MC_VER < MC_1_21_5
|
||||||
|
@Shadow
|
||||||
@Inject(method = "updateLightTexture(F)V", at = @At("RETURN"))
|
@Final
|
||||||
public void updateLightTexture(float partialTicks, CallbackInfo ci)
|
private TextureTarget target;
|
||||||
{
|
|
||||||
IMinecraftClientWrapper mc = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class);
|
|
||||||
if (mc == null || mc.getWrappedClientLevel() == null)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
IClientLevelWrapper clientLevel = mc.getWrappedClientLevel();
|
|
||||||
MinecraftRenderWrapper.INSTANCE.updateLightmap(this.lightPixels, clientLevel);
|
|
||||||
}
|
|
||||||
#else
|
#else
|
||||||
|
@Shadow
|
||||||
|
@Final
|
||||||
|
private GpuTexture texture;
|
||||||
|
#endif
|
||||||
|
|
||||||
@Shadow @Final private TextureTarget target;
|
|
||||||
@Inject(method = "updateLightTexture(F)V", at = @At("RETURN"))
|
@Inject(method = "updateLightTexture(F)V", at = @At("RETURN"))
|
||||||
public void updateLightTexture(float partialTicks, CallbackInfo ci)
|
public void updateLightTexture(float partialTicks, CallbackInfo ci)
|
||||||
{
|
{
|
||||||
@@ -70,9 +74,21 @@ public class MixinLightTexture
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
IClientLevelWrapper clientLevel = mc.getWrappedClientLevel();
|
IClientLevelWrapper clientLevel = mc.getWrappedClientLevel();
|
||||||
MinecraftRenderWrapper.INSTANCE.setLightmapId(this.target.getColorTextureId(), clientLevel);
|
MinecraftRenderWrapper renderWrapper = (MinecraftRenderWrapper)SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class);
|
||||||
|
|
||||||
|
#if MC_VER < MC_1_21_3
|
||||||
|
renderWrapper.updateLightmap(this.lightPixels, clientLevel);
|
||||||
|
#elif MC_VER < MC_1_21_5
|
||||||
|
renderWrapper.setLightmapId(this.target.getColorTextureId(), clientLevel);
|
||||||
|
#elif MC_VER < MC_1_21_9
|
||||||
|
GlTexture glTexture = (GlTexture) this.texture;
|
||||||
|
renderWrapper.setLightmapId(glTexture.glId(), clientLevel);
|
||||||
|
#else
|
||||||
|
int id = NeoforgeTextureUnwrapper.getGlTextureIdFromGpuTexture(this.texture);
|
||||||
|
renderWrapper.setLightmapId(id, clientLevel);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -12,7 +12,7 @@ import com.seibel.distanthorizons.core.wrapperInterfaces.IVersionConstants;
|
|||||||
import com.seibel.distanthorizons.coreapi.ModInfo;
|
import com.seibel.distanthorizons.coreapi.ModInfo;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.gui.screens.TitleScreen;
|
import net.minecraft.client.gui.screens.TitleScreen;
|
||||||
import org.apache.logging.log4j.Logger;
|
import com.seibel.distanthorizons.core.logging.DhLogger;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.Unique;
|
import org.spongepowered.asm.mixin.Unique;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
@@ -29,7 +29,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
|||||||
public class MixinMinecraft
|
public class MixinMinecraft
|
||||||
{
|
{
|
||||||
@Unique
|
@Unique
|
||||||
private static final Logger LOGGER = DhLoggerBuilder.getLogger(MixinMinecraft.class.getSimpleName());
|
private static final DhLogger LOGGER = new DhLoggerBuilder().build();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Can be enabled for testing the auto updater UI. <br/>
|
* Can be enabled for testing the auto updater UI. <br/>
|
||||||
|
|||||||
+6
@@ -1,6 +1,8 @@
|
|||||||
package com.seibel.distanthorizons.neoforge.mixins.client;
|
package com.seibel.distanthorizons.neoforge.mixins.client;
|
||||||
|
|
||||||
|
#if MC_VER < MC_1_21_5
|
||||||
import com.mojang.blaze3d.platform.GlStateManager;
|
import com.mojang.blaze3d.platform.GlStateManager;
|
||||||
|
#endif
|
||||||
import com.mojang.blaze3d.platform.TextureUtil;
|
import com.mojang.blaze3d.platform.TextureUtil;
|
||||||
import com.seibel.distanthorizons.core.config.Config;
|
import com.seibel.distanthorizons.core.config.Config;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
@@ -15,6 +17,9 @@ import org.spongepowered.asm.mixin.injection.Redirect;
|
|||||||
@Mixin(TextureUtil.class)
|
@Mixin(TextureUtil.class)
|
||||||
public class MixinTextureUtil
|
public class MixinTextureUtil
|
||||||
{
|
{
|
||||||
|
// TODO fix for MC 1.21.5+
|
||||||
|
|
||||||
|
#if MC_VER < MC_1_21_5
|
||||||
@Redirect(method = "prepareImage(Lcom/mojang/blaze3d/platform/NativeImage$InternalGlFormat;IIII)V",
|
@Redirect(method = "prepareImage(Lcom/mojang/blaze3d/platform/NativeImage$InternalGlFormat;IIII)V",
|
||||||
at = @At(value = "INVOKE", target = "Lcom/mojang/blaze3d/platform/GlStateManager;_texParameter(IIF)V"), remap = false)
|
at = @At(value = "INVOKE", target = "Lcom/mojang/blaze3d/platform/GlStateManager;_texParameter(IIF)V"), remap = false)
|
||||||
private static void setLodBias(int target, int pname, float param)
|
private static void setLodBias(int target, int pname, float param)
|
||||||
@@ -27,5 +32,6 @@ public class MixinTextureUtil
|
|||||||
GlStateManager._texParameter(target, pname, biasValue);
|
GlStateManager._texParameter(target, pname, biasValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
+46
@@ -0,0 +1,46 @@
|
|||||||
|
package com.seibel.distanthorizons.neoforge.mixins.server;
|
||||||
|
|
||||||
|
#if MC_VER < MC_1_21_4
|
||||||
|
|
||||||
|
import net.minecraft.world.entity.Entity;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
|
||||||
|
@Mixin(Entity.class)
|
||||||
|
public class MixinLevelTicks<T>
|
||||||
|
{
|
||||||
|
// dummy mixin to make the loader happy
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
import com.seibel.distanthorizons.common.wrappers.DependencySetupDoneCheck;
|
||||||
|
import net.minecraft.world.ticks.LevelTicks;
|
||||||
|
import net.minecraft.world.ticks.ScheduledTick;
|
||||||
|
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;
|
||||||
|
|
||||||
|
@Mixin(LevelTicks.class) // available in 1.18.2+, but only needed in 1.21.4+
|
||||||
|
public class MixinLevelTicks<T>
|
||||||
|
{
|
||||||
|
// TODO put in a common location
|
||||||
|
private static boolean isWorldGenThread()
|
||||||
|
{ return DependencySetupDoneCheck.isDone && DependencySetupDoneCheck.getIsCurrentThreadDistantGeneratorThread.get(); }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Inject(method = "schedule", at = @At(value = "HEAD"), cancellable = true)
|
||||||
|
private void onChunkSave(ScheduledTick<T> tick, CallbackInfo ci)
|
||||||
|
{
|
||||||
|
// In MC 1.21.4 an error check was added to log attempting to schedule ticks for unloaded chunks
|
||||||
|
// this caused a lot of unnecessary errors when generating sand (FallingBlock.class).
|
||||||
|
if (isWorldGenThread())
|
||||||
|
{
|
||||||
|
ci.cancel();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
+82
@@ -0,0 +1,82 @@
|
|||||||
|
package com.seibel.distanthorizons.neoforge.wrappers;
|
||||||
|
|
||||||
|
import com.seibel.distanthorizons.common.wrappers.minecraft.MinecraftRenderWrapper;
|
||||||
|
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import com.seibel.distanthorizons.core.logging.DhLogger;
|
||||||
|
|
||||||
|
#if MC_VER < MC_1_21_9
|
||||||
|
#else
|
||||||
|
import com.mojang.blaze3d.opengl.GlTexture;
|
||||||
|
import com.mojang.blaze3d.textures.GpuTexture;
|
||||||
|
import net.neoforged.neoforge.client.blaze3d.validation.ValidationGpuTexture;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
import java.lang.invoke.MethodHandles;
|
||||||
|
|
||||||
|
public class NeoforgeMinecraftRenderWrapper extends MinecraftRenderWrapper
|
||||||
|
{
|
||||||
|
public static final NeoforgeMinecraftRenderWrapper INSTANCE = new NeoforgeMinecraftRenderWrapper();
|
||||||
|
|
||||||
|
private static final DhLogger LOGGER = new DhLoggerBuilder().build();
|
||||||
|
private static final Minecraft MC = Minecraft.getInstance();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getDepthTextureId()
|
||||||
|
{
|
||||||
|
#if MC_VER < MC_1_21_9
|
||||||
|
// no special handling required,
|
||||||
|
// both neo/fabric uses the same back end objects
|
||||||
|
return super.getDepthTextureId();
|
||||||
|
#else
|
||||||
|
try
|
||||||
|
{
|
||||||
|
GpuTexture gpuTexture = this.getRenderTarget().getDepthTexture();
|
||||||
|
int id = NeoforgeTextureUnwrapper.getGlTextureIdFromGpuTexture(gpuTexture);
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
// only log this error once per session
|
||||||
|
if (!this.depthTextureCastFailLogged)
|
||||||
|
{
|
||||||
|
this.depthTextureCastFailLogged = true;
|
||||||
|
LOGGER.error("Unable to cast render Target depth texture to GlTexture. MC or a rendering mod may have changed the object type.", e);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getColorTextureId()
|
||||||
|
{
|
||||||
|
#if MC_VER < MC_1_21_9
|
||||||
|
// no special handling required,
|
||||||
|
// both neo/fabric uses the same back end objects
|
||||||
|
return super.getColorTextureId();
|
||||||
|
#else
|
||||||
|
try
|
||||||
|
{
|
||||||
|
GpuTexture gpuTexture = this.getRenderTarget().getColorTexture();
|
||||||
|
int id = NeoforgeTextureUnwrapper.getGlTextureIdFromGpuTexture(gpuTexture);
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
// only log this error once per session
|
||||||
|
if (!this.colorTextureCastFailLogged)
|
||||||
|
{
|
||||||
|
this.colorTextureCastFailLogged = true;
|
||||||
|
LOGGER.error("Unable to cast render Target color texture to ValidationGpuTexture or GlTexture. MC, Neoforge, or a rendering mod may have changed the object type.", e);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
+39
@@ -0,0 +1,39 @@
|
|||||||
|
package com.seibel.distanthorizons.neoforge.wrappers;
|
||||||
|
|
||||||
|
#if MC_VER < MC_1_21_9
|
||||||
|
public class NeoforgeTextureUnwrapper
|
||||||
|
{ /* not needed for older MC versions */ }
|
||||||
|
#else
|
||||||
|
|
||||||
|
import com.mojang.blaze3d.opengl.GlTexture;
|
||||||
|
import com.mojang.blaze3d.textures.GpuTexture;
|
||||||
|
import net.neoforged.neoforge.client.blaze3d.validation.ValidationGpuTexture;
|
||||||
|
|
||||||
|
public class NeoforgeTextureUnwrapper
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* if Neoforge texture validation is enabled the GlTexture object will be wrapped with a
|
||||||
|
* Neoforge specific ValidationGpuTexture object.
|
||||||
|
* This helper allows us to get the underlying OpenGL texture ID
|
||||||
|
* regardless of what Neoforge returns.
|
||||||
|
*/
|
||||||
|
public static int getGlTextureIdFromGpuTexture(GpuTexture gpuTexture) throws ClassCastException
|
||||||
|
{
|
||||||
|
GlTexture glTexture;
|
||||||
|
|
||||||
|
if (gpuTexture instanceof ValidationGpuTexture)
|
||||||
|
{
|
||||||
|
ValidationGpuTexture validationTexture = (ValidationGpuTexture) gpuTexture;
|
||||||
|
glTexture = (GlTexture)validationTexture.getRealTexture();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
glTexture = (GlTexture) gpuTexture;
|
||||||
|
}
|
||||||
|
|
||||||
|
int id = glTexture.glId();
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif
|
||||||
@@ -8,7 +8,8 @@
|
|||||||
"server.MixinServerPlayer",
|
"server.MixinServerPlayer",
|
||||||
"server.MixinTFChunkGenerator",
|
"server.MixinTFChunkGenerator",
|
||||||
"server.MixinTracingExecutor",
|
"server.MixinTracingExecutor",
|
||||||
"server.MixinUtilBackgroundThread"
|
"server.MixinUtilBackgroundThread",
|
||||||
|
"server.MixinLevelTicks"
|
||||||
],
|
],
|
||||||
"client": [
|
"client": [
|
||||||
"client.MixinClientPacketListener",
|
"client.MixinClientPacketListener",
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ loaderVersion = "*" # // mandatory. Allow all forge versions as we are definding
|
|||||||
license = "LGPL"
|
license = "LGPL"
|
||||||
issueTrackerURL = "${issues}"
|
issueTrackerURL = "${issues}"
|
||||||
|
|
||||||
|
# https://docs.neoforged.net/docs/gettingstarted/modfiles/#neoforgemodstoml
|
||||||
|
|
||||||
|
|
||||||
[[mods]] #//mandatory
|
[[mods]] #//mandatory
|
||||||
modId = "distanthorizons" #//mandatory
|
modId = "distanthorizons" #//mandatory
|
||||||
@@ -32,4 +34,11 @@ issueTrackerURL = "${issues}"
|
|||||||
type = "required"
|
type = "required"
|
||||||
versionRange = "${compatible_forgemc_versions}" # Where we set what version of mc it is avalible for
|
versionRange = "${compatible_forgemc_versions}" # Where we set what version of mc it is avalible for
|
||||||
ordering = "NONE"
|
ordering = "NONE"
|
||||||
side = "BOTH"
|
side = "BOTH"
|
||||||
|
|
||||||
|
[[dependencies.distanthorizons]]
|
||||||
|
modId = "neoforge"
|
||||||
|
type = "required"
|
||||||
|
versionRange = "${neoforge_version_range}"
|
||||||
|
ordering = "NONE"
|
||||||
|
side = "BOTH"
|
||||||
|
|||||||
@@ -0,0 +1,46 @@
|
|||||||
|
This directory contains the native files of libraries that were modified for relocation. They will be copied from here during the normal build steps.
|
||||||
|
|
||||||
|
Before adding/updating a library, make sure you have Python 3.8+ installed and check the instructions below.
|
||||||
|
|
||||||
|
How to add a library's natives:
|
||||||
|
|
||||||
|
1. In `build.gradle`:
|
||||||
|
|
||||||
|
- Make sure the target package is the same length or shorter (untested) than the source package. Underscores in native methods will be mapped to `_1` so account for that as well.
|
||||||
|
- Exclude the native files and add them as `relocateNative` (see example).
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
```groovy
|
||||||
|
relocate "org.sqlite", "dh_sqlite", {
|
||||||
|
exclude "org/sqlite/native/**"
|
||||||
|
}
|
||||||
|
|
||||||
|
transform(NativeTransformer) {
|
||||||
|
// NativeTransformer configuration
|
||||||
|
rootDir = project.rootDir
|
||||||
|
|
||||||
|
// Replace native strings, e.g. used in calls back to Java
|
||||||
|
relocateNative "org/sqlite", "dh_sqlite"
|
||||||
|
// Rename native methods used when calling from Java
|
||||||
|
relocateNative "org_sqlite", "dh_1sqlite"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
How to update a library's natives:
|
||||||
|
|
||||||
|
1. Delete the library's folder in cache/.
|
||||||
|
2. It will repopulate during the next build.
|
||||||
|
|
||||||
|
Why does this step exist?
|
||||||
|
|
||||||
|
- Native files are not handled by the shadow plugin correctly.
|
||||||
|
- I preferred it as a more streamlined approach, although a bit hacky.
|
||||||
|
- Possible alternatives:
|
||||||
|
- Use edited libraries' source code: although more straightforward, it requires maintaining and updating the repositories for the libraries being added
|
||||||
|
- Interfacing with the necessary libraries directly: an absolute mess for technical reasons
|
||||||
|
|
||||||
|
What are libraries used?
|
||||||
|
|
||||||
|
- LIEF: for fixing binaries after replacing strings
|
||||||
|
- apple-codesign: for re-signing Mac binaries, since their signatures get invalidated after previous steps
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user