Compare commits
180 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 004059dd9f | |||
| 4290cdf8c6 | |||
| 4d038fc5e6 | |||
| 0146d62c2a | |||
| 4e6255dc2b | |||
| 4d73c3ecb8 | |||
| d0dc3ec9bc | |||
| ee922236a0 | |||
| bf088ab29c | |||
| 40102521a1 | |||
| eb491144f3 | |||
| a14748ac75 | |||
| 0c5f38a00b | |||
| feb6dd41b7 | |||
| a093524939 | |||
| 5cc7bebbe5 | |||
| 32a256619f | |||
| f93e648f69 | |||
| 41f022df99 | |||
| c84aac7e45 | |||
| 4e4fbbe48c | |||
| 7265e2b631 | |||
| 0a11f310cf | |||
| a6143780fa | |||
| 761f802ced | |||
| 2e7cc9f4b6 | |||
| 4e6e727799 | |||
| 2da444d03c | |||
| f4f234a159 | |||
| e87823aa29 | |||
| 56167a137e | |||
| 91ac4309df | |||
| 8a5bca3136 | |||
| ec8d1b5538 | |||
| 0ebe8db268 | |||
| 3bba08723f | |||
| 6a6a87a3f7 | |||
| 0ccdcfbb6d | |||
| aa084c885d | |||
| e3a8a7782e | |||
| c578ae0fa4 | |||
| f17bc1eccd | |||
| 08c31e5999 | |||
| dd341c9a22 | |||
| 733fb8e871 | |||
| 4764f0969a | |||
| 41f8c8cfa4 | |||
| 42bcc28d3e | |||
| b878faac96 | |||
| 32c1cc29f8 | |||
| 838d82589b | |||
| b62af66f4b | |||
| 794f524ae3 | |||
| a38551b3d0 | |||
| 03c4926b09 | |||
| 982bf951e1 | |||
| a887e35285 | |||
| 172f2b088d | |||
| 6d7b557c36 | |||
| 9959ebc196 | |||
| d868b8fc72 | |||
| 297c8a1a1e | |||
| e809429a8c | |||
| 200ad05f4c | |||
| 9b4276c29b | |||
| 038073d34d | |||
| 8d32ab9bdb | |||
| 9390b8bc4d | |||
| 0d165860fb | |||
| 4135fa6211 | |||
| 1d89467022 | |||
| e21ac626b3 | |||
| aa73a30ac4 | |||
| 9a8f14c7d3 | |||
| d7618d73c3 | |||
| 5aca47b357 | |||
| 666ab1319b | |||
| 50663edc76 | |||
| 1fbc37f8e7 | |||
| 5f437f8a4e | |||
| 6130c65c48 | |||
| 1e19dfd6e8 | |||
| f866243d5c | |||
| af04c6d995 | |||
| 46bf8d0188 | |||
| fc62c78136 | |||
| 93c2bf530f | |||
| 51b543a23e | |||
| dab5373231 | |||
| 17f274a7b4 | |||
| 841e5ba492 | |||
| 50339c94e7 | |||
| d2ad35ad05 | |||
| 0d65578e6a | |||
| 526df4f184 | |||
| aa6cbd1b7d | |||
| 92f0703723 | |||
| 064241333b | |||
| 39b77c783b | |||
| 0c8717a0da | |||
| 7f89a1a2cc | |||
| 5f16f81d58 | |||
| 10bbcc79d3 | |||
| ffc9771b17 | |||
| 091b115aad | |||
| c3bdc22e28 | |||
| 28d4cc86a9 | |||
| bb6e29f254 | |||
| ea0d4ba7d8 | |||
| 0504882afd | |||
| 0156f03e91 | |||
| d2acaba5c7 | |||
| 60e4128316 | |||
| dc8aa7624b | |||
| 941aeedee0 | |||
| 4d8ce3b5ea | |||
| 6044d24a48 | |||
| d597634ac6 | |||
| cf8b0329bb | |||
| 24520824e9 | |||
| 0d7b0f9fe4 | |||
| 61460f9ac0 | |||
| 14d64d535a | |||
| b00c252f17 | |||
| 0fe017df74 | |||
| 4ae7083dcf | |||
| 7d5357dec8 | |||
| 2bb2f5a233 | |||
| fee1c98a34 | |||
| e787d7d317 | |||
| ed52efa72b | |||
| 963d22b2f5 | |||
| 8714be1dc7 | |||
| 04ddd83519 | |||
| 5b81ca2716 | |||
| 6f8c7e8249 | |||
| fabad7158e | |||
| bae7e44dd8 | |||
| 926c7924df | |||
| 704a2ff217 | |||
| 871c6031b8 | |||
| afb0a57920 | |||
| 1787d2c6d9 | |||
| 1a07fb83b6 | |||
| 4d2ee292bb | |||
| 0fdde61fe5 | |||
| ae8a4912a6 | |||
| ffd8ea8751 | |||
| 4cd10a82fd | |||
| 4955d22649 | |||
| 425b761f8e | |||
| ab3bfd457f | |||
| 0faa64112a | |||
| 46519b096c | |||
| cb7d980e15 | |||
| 6c1562ac33 | |||
| 5e17e4ea8c | |||
| b8e7b14fbb | |||
| 5d8eb185bc | |||
| 7325cedba6 | |||
| e5043d6d9b | |||
| 13e53a18e3 | |||
| dd60c7620f | |||
| 83c01cabfb | |||
| a95171dbbe | |||
| 10d542ed14 | |||
| 7e1c55a0c5 | |||
| 4e25d318ec | |||
| c4228f4e63 | |||
| 1411091f60 | |||
| 6a2278949e | |||
| 374b859882 | |||
| a98bdb94b8 | |||
| de390f5d70 | |||
| 9d4968351b | |||
| e99fbb76bf | |||
| fd175d2f36 | |||
| 0db862e42b | |||
| 58f5d64f91 | |||
| bb54a94acd |
@@ -34,3 +34,6 @@ build.properties
|
||||
|
||||
# Sqlite databases
|
||||
*.sqlite
|
||||
|
||||
# Don't add access transformers to git as it's dynamically generated
|
||||
accesstransformer.cfg
|
||||
|
||||
+11
-4
@@ -30,7 +30,7 @@ build:
|
||||
stage: build
|
||||
parallel:
|
||||
matrix:
|
||||
- MC_VER: ["1.16.5", "1.17.1", "1.18.2", "1.19.2", "1.19.4", "1.20.1", "1.20.2"]
|
||||
- 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"]
|
||||
script:
|
||||
# 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/;
|
||||
@@ -40,17 +40,24 @@ build:
|
||||
name: "NightlyBuild_${MC_VER}-${CI_COMMIT_SHORT_SHA}-${CI_COMMIT_TIMESTAMP}"
|
||||
paths:
|
||||
- Merged/*.jar
|
||||
- quilt/build/libs/*.jar
|
||||
- fabric/build/libs/*.jar
|
||||
- forge/build/libs/*.jar
|
||||
- quilt/build/libs/*.jar
|
||||
- neoforge/build/libs/*.jar
|
||||
exclude:
|
||||
# TODO: There is a lot of duplicate stuff here, try to maybe make it smaller
|
||||
- fabric/build/libs/*-all.jar
|
||||
- fabric/build/libs/*-dev.jar
|
||||
- fabric/build/libs/*-sources.jar
|
||||
- forge/build/libs/*-all.jar
|
||||
- forge/build/libs/*-sources.jar
|
||||
- quilt/build/libs/*-all.jar
|
||||
- quilt/build/libs/*-dev.jar
|
||||
- quilt/build/libs/*-sources.jar
|
||||
- forge/build/libs/*-all.jar
|
||||
- forge/build/libs/*-dev.jar
|
||||
- forge/build/libs/*-sources.jar
|
||||
- neoforge/build/libs/*-all.jar
|
||||
- neoforge/build/libs/*-dev.jar
|
||||
- neoforge/build/libs/*-sources.jar
|
||||
expire_in: 14 days
|
||||
when: always
|
||||
extends: .build_java
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
## Chcek off each item in this list before submitting:
|
||||
## Check off each item in this list before submitting:
|
||||
|
||||
<!--
|
||||
To mark a section as complete either put an "x" in between the square brackets, example: "[x]"
|
||||
@@ -6,13 +6,13 @@ Or click the checkbox once the issue has been created.
|
||||
-->
|
||||
|
||||
1. [ ] Check the FAQ to see if your issue has already been reported and has a solution:
|
||||
[Problems-and-solutions](https://gitlab.com/jeseibel/minecraft-lod-mod/-/wikis/2-frequently-asked-questions/2-problems-and-solutions/Problems-and-Solutions)
|
||||
[Problems-and-solutions](https://gitlab.com/jeseibel/distant-horizons/-/wikis/2-frequently-asked-questions/2-problems-and-solutions/Problems-and-Solutions)
|
||||
|
||||
2. [ ] Make sure you are not using any mods on the incompatible list:
|
||||
[Mod support FAQ](https://gitlab.com/jeseibel/minecraft-lod-mod/-/wikis/2-frequently-asked-questions/4-mod-support/Mod-Support)
|
||||
[Mod support FAQ](https://gitlab.com/jeseibel/distant-horizons/-/wikis/2-frequently-asked-questions/4-mod-support/Mod-Support)
|
||||
|
||||
3. [ ] Check the existing issues to verify that your bug hasn't already been submitted:
|
||||
[Issues](https://gitlab.com/jeseibel/minecraft-lod-mod/-/issues/)
|
||||
[Issues](https://gitlab.com/jeseibel/distant-horizons/-/issues/)
|
||||
|
||||
4. [ ] Upload Minecraft's crash report and/or log. \
|
||||
Minecraft crash reports are located in: `.minecraft/crash-reports` \
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
- [ ] Check the existing [feature requests](https://gitlab.com/jeseibel/minecraft-lod-mod/-/issues/?sort=updated_desc&state=opened&label_name%5B%5D=Feature) to verify that your feature hasn't already been suggested.
|
||||
- [ ] Check the existing [feature requests](https://gitlab.com/jeseibel/distant-horizons/-/issues/?sort=updated_desc&state=opened&label_name%5B%5D=Feature) to verify that your feature hasn't already been suggested.
|
||||
|
||||
1. **Describe the feature**:
|
||||
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
1. Check the existing [improvement requests](https://gitlab.com/jeseibel/minecraft-lod-mod/-/issues/?sort=updated_desc&state=all&label_name%5B%5D=Improvement) to verify that your improvement hasn't already been suggested.
|
||||
1. Check the existing [improvement requests](https://gitlab.com/jeseibel/distant-horizons/-/issues/?sort=updated_desc&state=all&label_name%5B%5D=Improvement) to verify that your improvement hasn't already been suggested.
|
||||
|
||||
2. **Describe the improvement**:
|
||||
|
||||
@@ -20,6 +20,14 @@ If you want to see a quick demo, check out a video covering the mod here:
|
||||
|
||||
### This branch supports the following versions of Minecraft:
|
||||
|
||||
#### 1.20.4, 1.20.3 (Default)
|
||||
Fabric: 0.15.1\
|
||||
Fabric API: 0.91.2+1.20.4\
|
||||
Forge: 49.0.30\
|
||||
NeoForge: 118-beta\
|
||||
Parchment: 1.20.2:2023.12.10\
|
||||
Modmenu: 9.0.0-pre.1
|
||||
|
||||
#### 1.20.2
|
||||
Fabric: 0.14.24\
|
||||
Fabric API: 0.90.4+1.20.2\
|
||||
@@ -27,7 +35,7 @@ Forge: 48.0.13\
|
||||
Parchment: 1.20.1:2023.09.03\
|
||||
Modmenu: 8.0.0
|
||||
|
||||
#### 1.20.1, 1.20 (Default)
|
||||
#### 1.20.1, 1.20
|
||||
Fabric: 0.14.24\
|
||||
Fabric API: 0.90.4+1.20.1\
|
||||
Forge: 47.2.1\
|
||||
@@ -77,10 +85,10 @@ Modmenu: 1.16.22
|
||||
|
||||
### Plugin and Library versions
|
||||
|
||||
Fabric loom: 1.1.+\
|
||||
Forge gradle (Using Architectury): 3.4-SNAPSHOT\
|
||||
Gradle: 8.5\
|
||||
Fabric loom: 1.4-SNAPSHOT\
|
||||
Architectury loom (Forge gradle replacement): 1.4-SNAPSHOT\
|
||||
Sponge vanilla gradle: 0.2.1-SNAPSHOT\
|
||||
Sponge mixin: 0.8.5\
|
||||
Java Preprocessor plugin: Manifold Preprocessor
|
||||
|
||||
<br>
|
||||
@@ -115,7 +123,7 @@ To switch between different Minecraft versions, change `mcVer=1.?` in the `gradl
|
||||
If running in an IDE, to ensure the IDE noticed the version change, run any gradle command to refresh gradle. (In IntellJ you will also need to do a gradle sync if it didn't happen automatically.)
|
||||
>Note: There may be a `java.nio.file.FileSystemException` thrown when running the command after switching versions. To fix it, either restart your IDE (as your IDE is probably locking a file) or use a tool like LockHunter to unlock the linked file(s). (Generally it is a lib file under `common\build\lib`, `forge\build\lib`, or `fabric\build\lib`). \
|
||||
> If anyone knows how to solve this issue please let us know here: \
|
||||
> https://gitlab.com/jeseibel/minecraft-lod-mod/-/issues/233
|
||||
> https://gitlab.com/jeseibel/distant-horizons/-/issues/233
|
||||
|
||||
|
||||
<br>
|
||||
@@ -134,7 +142,7 @@ From the File Explorer:
|
||||
6. The compiled jar file will be in the folder `Merged`
|
||||
|
||||
From the command line:
|
||||
1. `git clone --recurse-submodules https://gitlab.com/jeseibel/minecraft-lod-mod.git`
|
||||
1. `git clone --recurse-submodules https://gitlab.com/jeseibel/distant-horizons.git`
|
||||
2. `cd minecraft-lod-mod`
|
||||
3. `./gradlew assemble`
|
||||
4. `./gradlew mergeJars`
|
||||
|
||||
+177
-177
@@ -1,78 +1,15 @@
|
||||
plugins {
|
||||
id "java"
|
||||
|
||||
// Plugin to handle dependencies
|
||||
// Plugin to put dependencies inside our final jar
|
||||
id "com.github.johnrengelman.shadow" version '7.1.2' apply false
|
||||
|
||||
// Plugin to create merged jars
|
||||
id "io.github.pacifistmc.forgix" version "1.2.6"
|
||||
|
||||
// Manifold preprocessor
|
||||
id "systems.manifold.manifold-gradle-plugin" version "0.0.2-alpha"
|
||||
|
||||
// Provides mc libraries to core
|
||||
// id "org.spongepowered.gradle.vanilla" version '0.2.1-SNAPSHOT' apply false
|
||||
|
||||
// Architectury is used here only as a replacement for forge's own loom
|
||||
id "dev.architectury.loom" version "1.1.+" apply false
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the list of preprocessors to use.
|
||||
*
|
||||
* @param mcVers array of all MC versions
|
||||
* @param mcIndex array index of the currently active MC version
|
||||
*/
|
||||
def writeBuildGradlePredefine(List<String> mcVers, int mcIndex) {
|
||||
ArrayList<String> redefineList = new ArrayList<String>()
|
||||
|
||||
for (int i = 0; i < mcVers.size(); i++) {
|
||||
String mcStr = mcVers[i].replace(".", "_")
|
||||
|
||||
if (mcIndex < i) {
|
||||
// exclusive before
|
||||
// FIXME doesn't function correctly for 1.16.5 (IE the first item in the list)
|
||||
redefineList.add("PRE_MC_" + mcStr)
|
||||
}
|
||||
if (mcIndex <= i) {
|
||||
// inclusive before
|
||||
redefineList.add("PRE_AND_MC_" + mcStr)
|
||||
}
|
||||
|
||||
if (mcIndex == i) {
|
||||
// exact
|
||||
redefineList.add("MC_" + mcStr)
|
||||
}
|
||||
|
||||
if (mcIndex > i) {
|
||||
// inclusive after
|
||||
redefineList.add("POST_AND_MC_" + mcStr)
|
||||
}
|
||||
if (mcIndex >= i) {
|
||||
// exclusive after
|
||||
redefineList.add("POST_MC_" + mcStr)
|
||||
}
|
||||
}
|
||||
|
||||
// Build the list of preprocessors to use
|
||||
StringBuilder sb = new StringBuilder()
|
||||
|
||||
sb.append("# DON'T TOUCH THIS FILE, This is handled by the build script\n")
|
||||
|
||||
// Check if this is a development build
|
||||
if (mod_version.toLowerCase().contains("dev")) {
|
||||
// WARNING: only use this for logging, we don't want to have confusion
|
||||
// when a method doesn't work correctly in the release build.
|
||||
sb.append("DEV_BUILD")
|
||||
sb.append("=\n")
|
||||
}
|
||||
|
||||
// Build the MC version preprocessors
|
||||
for (String redefinedVersion : redefineList) {
|
||||
sb.append(redefinedVersion)
|
||||
sb.append("=\n")
|
||||
}
|
||||
new File(projectDir, "build.properties").text = sb.toString()
|
||||
// Unimined is our all in one solution to minecraft loaders
|
||||
// id "xyz.wagyourtail.unimined" version "1.2.0-SNAPSHOT" apply false // Unstable Release (TODO: Check back to see when the unstable branch fixes forge run without the jank)
|
||||
id "xyz.wagyourtail.unimined" version "1.1.2-SNAPSHOT" apply false // LTS Release
|
||||
}
|
||||
|
||||
|
||||
@@ -81,7 +18,42 @@ project.gradle.ext.getProperties().each { prop ->
|
||||
rootProject.ext.set(prop.key, prop.value)
|
||||
// println "Added prop [key:" + prop.key + ", value:" + prop.value + "]"
|
||||
}
|
||||
// Sets up manifold stuff
|
||||
|
||||
|
||||
/**
|
||||
* Creates the list of preprocessors to use.
|
||||
*
|
||||
* @param mcVers array of all MC versions
|
||||
* @param mcIndex array index of the currently active MC version
|
||||
*/
|
||||
def writeBuildGradlePredefine(List<String> mcVers, int mcIndex)
|
||||
{
|
||||
// Build the list of preprocessors to use
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
sb.append("# DON'T TOUCH THIS FILE, This is handled by the build script\n");
|
||||
|
||||
|
||||
for (int i = 0; i < mcVers.size(); i++)
|
||||
{
|
||||
String verStr = mcVers[i].replace(".", "_");
|
||||
sb.append("MC_" + verStr + "=" + i.toString() + "\n");
|
||||
|
||||
if (mcIndex == i)
|
||||
sb.append("MC_VER=" + i.toString() + "\n");
|
||||
}
|
||||
|
||||
|
||||
// Check if this is a development build
|
||||
if (mod_version.toLowerCase().contains("dev"))
|
||||
{
|
||||
// WARNING: only use this for logging, we don't want to have confusion
|
||||
// when a method doesn't work correctly in the release build.
|
||||
sb.append("DEV_BUILD=\n");
|
||||
}
|
||||
|
||||
new File(projectDir, "build.properties").text = sb.toString()
|
||||
}
|
||||
writeBuildGradlePredefine(rootProject.mcVers, rootProject.mcIndex)
|
||||
|
||||
|
||||
@@ -89,6 +61,7 @@ writeBuildGradlePredefine(rootProject.mcVers, rootProject.mcIndex)
|
||||
|
||||
// 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")
|
||||
|
||||
// Forgix settings (used for merging jars)
|
||||
forgix {
|
||||
group = "com.seibel.distanthorizons"
|
||||
@@ -98,6 +71,12 @@ forgix {
|
||||
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 {
|
||||
@@ -113,7 +92,7 @@ forgix {
|
||||
}
|
||||
|
||||
subprojects { p ->
|
||||
// Does the same as "p == project(":common") || p == project(":fabric") || p == project(":quilt") || p == project(":forge") || p == project("WhateverWeAddLaterOn")"
|
||||
// Does the same as "p == project(":common") || p == project(":fabric") || p == project(":forge") || p == project("WhateverLoaderWeAddLaterOn")"
|
||||
// Useful later on so we dont have duplicated code
|
||||
def isMinecraftSubProject = p != project(":core") && p != project(":api")
|
||||
|
||||
@@ -121,65 +100,68 @@ subprojects { p ->
|
||||
// Apply plugins
|
||||
apply plugin: "java"
|
||||
apply plugin: "com.github.johnrengelman.shadow"
|
||||
if (isMinecraftSubProject)
|
||||
apply plugin: "systems.manifold.manifold-gradle-plugin"
|
||||
if (p == project(":core"))
|
||||
if (p == project(":core"))
|
||||
apply plugin: "application"
|
||||
// apply plugin: "org.spongepowered.gradle.vanilla" // Provides minecraft libraries
|
||||
|
||||
if (isMinecraftSubProject) {
|
||||
apply plugin: "xyz.wagyourtail.unimined"
|
||||
|
||||
// Apply forge's loom
|
||||
if (findProject(":forge") && p == project(":forge"))
|
||||
apply plugin: "dev.architectury.loom"
|
||||
unimined.minecraft(sourceSets.main, true) {
|
||||
version = rootProject.minecraft_version
|
||||
|
||||
def parchmentVersionParts = rootProject.parchment_version.split(":")
|
||||
mappings {
|
||||
mojmap()
|
||||
parchment(parchmentVersionParts[0], parchmentVersionParts[1])
|
||||
devNamespace "mojmap"
|
||||
}
|
||||
|
||||
runs {
|
||||
config("client") {
|
||||
workingDir = rootProject.file("run")
|
||||
}
|
||||
config("server") {
|
||||
workingDir = rootProject.file("run") // TODO: When running the server, would it be a better idea to change this to a different dir?
|
||||
disabled = true // TODO: Once server-side support is added, remove this
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Set the manifold version (may not be required tough)
|
||||
manifold {
|
||||
manifoldVersion = rootProject.manifold_version
|
||||
if (p != project(":common")) {
|
||||
tasks.withType(JavaCompile).configureEach {
|
||||
source(project(":common").sourceSets.main.java)
|
||||
source(project(":api").sourceSets.main.java)
|
||||
source(project(":core").sourceSets.main.java)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tasks.withType(GenerateModuleMetadata) {
|
||||
enabled = false
|
||||
}
|
||||
|
||||
// Disable testing for projects that aren't the core or api project.
|
||||
// If not done compiling will fail due to an issue with Manifold
|
||||
if (isMinecraftSubProject) {
|
||||
test {
|
||||
enabled = false
|
||||
}
|
||||
compileTestJava {
|
||||
enabled = false
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// set up custom configurations (configurations are a way to handle dependencies)
|
||||
configurations {
|
||||
// extends the shadowJar configuration
|
||||
shadowMe
|
||||
shadowMc // Configuration that doesn't contain coreProjects
|
||||
|
||||
// have implemented dependencies automatically embedded in the final jar
|
||||
implementation.extendsFrom(shadowMe)
|
||||
implementation.extendsFrom(shadowMc)
|
||||
|
||||
// Configuration fpr core & api
|
||||
coreProjects
|
||||
shadowMe.extendsFrom(coreProjects)
|
||||
|
||||
|
||||
// FIXME this additional configuration is necessary because forge
|
||||
// needs forgeRuntimeLibrary, although adding it to shadowMe
|
||||
// causes runtime issues where the libraries aren't properly added
|
||||
forgeShadowMe
|
||||
// this should match shadowMe pretty closely
|
||||
implementation.extendsFrom(forgeShadowMe)
|
||||
shadowMe.extendsFrom(forgeShadowMe)
|
||||
forgeRuntimeLibrary.extendsFrom(forgeShadowMe)
|
||||
|
||||
|
||||
if (isMinecraftSubProject && p != project(":common")) {
|
||||
// Shadow common
|
||||
common
|
||||
shadowCommon // Don't use shadow from the shadow plugin because we don't want IDEA to index this.
|
||||
compileClasspath.extendsFrom common
|
||||
runtimeClasspath.extendsFrom common
|
||||
developmentForge.extendsFrom common
|
||||
compileClasspath.extendsFrom coreProjects
|
||||
runtimeClasspath.extendsFrom coreProjects
|
||||
developmentForge.extendsFrom coreProjects
|
||||
|
||||
if (findProject(":fabricLike") && p != project(":fabricLike")) {
|
||||
// Shadow fabricLike
|
||||
fabricLike
|
||||
shadowFabricLike
|
||||
compileClasspath.extendsFrom fabricLike
|
||||
runtimeClasspath.extendsFrom fabricLike
|
||||
developmentForge.extendsFrom fabricLike
|
||||
}
|
||||
}
|
||||
// Add shaded libraries very early in the classpath (excluding coreProjects as that's added in a different way)
|
||||
minecraftLibraries.extendsFrom(shadowMc)
|
||||
}
|
||||
|
||||
|
||||
@@ -196,45 +178,47 @@ subprojects { p ->
|
||||
// shared dependencies //
|
||||
//=====================//
|
||||
|
||||
|
||||
// Manifold
|
||||
if (isMinecraftSubProject) {
|
||||
annotationProcessor("systems.manifold:manifold-preprocessor:${rootProject.manifold_version}")
|
||||
}
|
||||
|
||||
// Log4j
|
||||
// TODO: Change to shadowMe later to work in the standalone jar
|
||||
// TODO: Change to shadowCore later to work in the standalone jar
|
||||
// We cannot do this now as it would break Quilt
|
||||
implementation("org.apache.logging.log4j:log4j-api:${rootProject.log4j_version}")
|
||||
implementation("org.apache.logging.log4j:log4j-core:${rootProject.log4j_version}")
|
||||
|
||||
// JOML
|
||||
implementation("org.joml:joml:${rootProject.joml_version}")
|
||||
|
||||
// JUnit tests
|
||||
implementation("org.junit.jupiter:junit-jupiter:5.8.2")
|
||||
implementation("org.junit.jupiter:junit-jupiter-engine:5.8.2")
|
||||
implementation("junit:junit:4.13")
|
||||
|
||||
// JOML
|
||||
if (project.hasProperty("embed_joml") && embed_joml == "true")
|
||||
shadowMc("org.joml:joml:${rootProject.joml_version}")
|
||||
else
|
||||
implementation("org.joml:joml:${rootProject.joml_version}")
|
||||
|
||||
// Compression
|
||||
forgeShadowMe("org.lz4:lz4-java:${rootProject.lz4_version}")
|
||||
shadowMc("org.lz4:lz4-java:${rootProject.lz4_version}")
|
||||
|
||||
// Sqlite Database
|
||||
forgeShadowMe("org.xerial:sqlite-jdbc:${rootProject.sqlite_jdbc_version}")
|
||||
shadowMc("org.xerial:sqlite-jdbc:${rootProject.sqlite_jdbc_version}")
|
||||
|
||||
// NightConfig (includes Toml & Json)
|
||||
forgeShadowMe("com.electronwill.night-config:toml:${rootProject.nightconfig_version}")
|
||||
forgeShadowMe("com.electronwill.night-config:json:${rootProject.nightconfig_version}")
|
||||
shadowMc("com.electronwill.night-config:toml:${rootProject.nightconfig_version}")
|
||||
shadowMc("com.electronwill.night-config:json:${rootProject.nightconfig_version}")
|
||||
|
||||
// SVG (not needed atm)
|
||||
// forgeShadowMe("com.formdev:svgSalamander:${rootProject.svgSalamander_version}")
|
||||
//shadowMc("com.formdev:svgSalamander:${rootProject.svgSalamander_version}")
|
||||
|
||||
// Netty
|
||||
// Breaks 1.16.5
|
||||
//forgeShadowMe("io.netty:netty-all:${rootProject.netty_version}")
|
||||
//shadowMc("io.netty:netty-all:${rootProject.netty_version}")
|
||||
|
||||
// Remember, for lwjgl dependencies that arent included in Minecraft, you need to also need to add it to the ShadowJar thing
|
||||
forgeShadowMe("org.lwjgl:lwjgl-jawt:${rootProject.lwjgl_version}") {
|
||||
shadowMc("org.lwjgl:lwjgl-jawt:${rootProject.lwjgl_version}") {
|
||||
exclude group: "org.lwjgl", module: "lwjgl" // This module is imported by Minecraft so exclude it
|
||||
}
|
||||
|
||||
@@ -247,11 +231,12 @@ subprojects { p ->
|
||||
|
||||
// Add core
|
||||
if (isMinecraftSubProject) {
|
||||
coreProjects(project(":core")) {
|
||||
compileOnly(project(":core")) {
|
||||
// Remove Junit test libraries
|
||||
exclude group: "org.junit.jupiter", module: "junit-jupiter"
|
||||
exclude group: "org.junit.jupiter", module: "junit-jupiter-engine"
|
||||
exclude group: "junit", module: "junit"
|
||||
|
||||
// Removed dependencies
|
||||
transitive false
|
||||
}
|
||||
@@ -259,11 +244,12 @@ subprojects { p ->
|
||||
|
||||
// Add the api
|
||||
if (p != project(":api")) {
|
||||
coreProjects(project(":api")) {
|
||||
implementation(project(":api")) {
|
||||
// Remove Junit test libraries
|
||||
exclude group: "org.junit.jupiter", module: "junit-jupiter"
|
||||
exclude group: "org.junit.jupiter", module: "junit-jupiter-engine"
|
||||
exclude group: "junit", module: "junit"
|
||||
|
||||
// Removed dependencies
|
||||
transitive false
|
||||
}
|
||||
@@ -272,29 +258,19 @@ subprojects { p ->
|
||||
// Add common
|
||||
if (isMinecraftSubProject && p != project(":common")) {
|
||||
// Common
|
||||
common(project(":common")) { transitive false }
|
||||
shadowCommon(project(":common")) { transitive false }
|
||||
|
||||
// FabricLike
|
||||
if (findProject(":fabricLike") && p != project(":fabricLike")) {
|
||||
fabricLike(project(path: ":fabricLike")) { transitive false }
|
||||
shadowFabricLike(project(path: ":fabricLike")) { transitive false }
|
||||
}
|
||||
compileOnly(project(":common")) { transitive false }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
shadowJar {
|
||||
configurations = [project.configurations.shadowMe]
|
||||
configurations = [project.configurations.shadowMc]
|
||||
|
||||
if (isMinecraftSubProject && p != project(":common")) {
|
||||
configurations.push(project.configurations.shadowCommon) // Shadow the common subproject
|
||||
relocate "com.seibel.distanthorizons.common", "loaderCommon.${p.name}.com.seibel.distanthorizons.common" // Move the loader files to a different location
|
||||
|
||||
if (findProject(":fabricLike") && p != project(":fabricLike")) {
|
||||
configurations.push(project.configurations.shadowFabricLike) // Shadow the fabricLike subproject
|
||||
relocate "com.seibel.distanthorizons.fabriclike", "loaderCommon.${p.name}.com.seibel.distanthorizons.fabriclike" // Move the loader files to a different location
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
def librariesLocation = "distanthorizons.libraries"
|
||||
|
||||
// LWJGL
|
||||
@@ -307,6 +283,10 @@ subprojects { p ->
|
||||
// Sqlite Database
|
||||
//At the moment, there is a bug in this library which doesnt allow it to be relocated
|
||||
// relocate "org.sqlite", "${librariesLocation}.sqlite"
|
||||
|
||||
// JOML
|
||||
if (project.hasProperty("embed_joml") && embed_joml == "true")
|
||||
relocate "org.joml", "${librariesLocation}.joml"
|
||||
|
||||
// NightConfig (includes Toml & Json)
|
||||
relocate "com.electronwill.nightconfig", "${librariesLocation}.electronwill.nightconfig"
|
||||
@@ -325,7 +305,20 @@ subprojects { p ->
|
||||
|
||||
// Put stuff from gradle.properties into the mod info
|
||||
processResources {
|
||||
def resourceTargets = [ // Location of where to inject the properties
|
||||
duplicatesStrategy = DuplicatesStrategy.WARN
|
||||
// Include all the resources
|
||||
from project(":common").sourceSets.main.resources
|
||||
from project(":core").sourceSets.main.resources
|
||||
from project(":api").sourceSets.main.resources
|
||||
|
||||
// Copy accessWideners
|
||||
// FIXME: remove copyCommonLoaderResources and use this instead (and if you are removing that task, also remove copyCoreResources while your at it)
|
||||
// from project(":common").file("src/main/resources/${accessWidenerVersion}.distanthorizons.accesswidener")
|
||||
// into(file(p.file("build/resources/main")))
|
||||
rename "${accessWidenerVersion}.distanthorizons.accesswidener", "distanthorizons.accesswidener"
|
||||
|
||||
// Location of where to inject the properties
|
||||
def resourceTargets = [
|
||||
// Holds info like git commit
|
||||
// TODO: For some reason this script doesnt work with the core project
|
||||
"build_info.json",
|
||||
@@ -338,15 +331,15 @@ subprojects { p ->
|
||||
// The mixins for each of the loaders
|
||||
"DistantHorizons."+ p.name +".fabricLike.mixins.json"
|
||||
]
|
||||
def intoTargets = ["$buildDir/resources/main/"] // Location of the built resources folder
|
||||
def buildResourceTargets = ["$buildDir/resources/main/"] // Location of the built resources folder
|
||||
|
||||
// Fix forge version numbering system as it is weird
|
||||
// For whatever reason forge uses [1.18, 1.18.1, 1.18.2) instead of the standard ["1.18", "1.18.1", "1.18.2"] which make more sense
|
||||
// For whatever reason forge uses [1.18, 1.18.1, 1.18.2) instead of the standard ["1.18", "1.18.1", "1.18.2"]
|
||||
def compatible_forgemc_versions = "${compatible_minecraft_versions}".replaceAll("\"", "").replaceAll("]", ",)")
|
||||
// println compatible_forgemc_versions
|
||||
|
||||
// Quilt's custom contributors system
|
||||
// This has to be like
|
||||
// has to be in the format:
|
||||
// "Person": "Developer", "Another person": "Developer"
|
||||
def quilt_contributors = []
|
||||
def mod_author_list = mod_authors.replaceAll("\"", "").replace("[", "").replace("]", "").split(",")
|
||||
@@ -354,9 +347,9 @@ subprojects { p ->
|
||||
quilt_contributors.push("\"${dev.strip()}\": \"Developer\"")
|
||||
}
|
||||
quilt_contributors.reverse()
|
||||
// println quilt_contributors.join(", ")
|
||||
//println quilt_contributors.join(", ")
|
||||
|
||||
// TODOI: Find something we can use so we can basically re-map only when the jar is shadowed and relocated
|
||||
// TODO: Find something we can use so we can basically re-map only when the jar is shadowed and relocated
|
||||
// println p.tasks.findByName('shadowJar')
|
||||
|
||||
|
||||
@@ -371,6 +364,7 @@ subprojects { p ->
|
||||
println "Git or Git project not found"
|
||||
}
|
||||
|
||||
// The left side is what gets replaced in the mod info and the right side is where to get it from in the gradle.properties
|
||||
def replaceProperties = [
|
||||
version : mod_version,
|
||||
mod_name : mod_readable_name,
|
||||
@@ -394,15 +388,17 @@ subprojects { p ->
|
||||
fabric_incompatibility_list : fabric_incompatibility_list,
|
||||
fabric_recommend_list : fabric_recommend_list,
|
||||
]
|
||||
// The left side is what gets replaced in the mod info and the right side is where to get it from in the gradle.properties
|
||||
|
||||
|
||||
// replace any properties in the sub-projects with the values defined here
|
||||
inputs.properties replaceProperties
|
||||
replaceProperties.put "project", project
|
||||
replaceProperties.put("project", project)
|
||||
filesMatching(resourceTargets) {
|
||||
expand replaceProperties
|
||||
}
|
||||
|
||||
intoTargets.each { target ->
|
||||
|
||||
|
||||
// copy all our resources into the loader specific resource directory
|
||||
buildResourceTargets.each { target ->
|
||||
if (file(target).exists()) {
|
||||
copy {
|
||||
from(sourceSets.main.resources) {
|
||||
@@ -423,7 +419,7 @@ subprojects { p ->
|
||||
//// include "${accessWidenerVersion}.distanthorizons.accesswidener"
|
||||
|
||||
// Jank solution to remove all unused accesswideners
|
||||
// The line above would work..., except forge requires the original accesswidener file, meaning we require this jank solution to keep it
|
||||
// The line above would work..., except that (neo)forge (well, mainly architectury) requires the original accesswidener file, meaning we require this jank solution to keep it
|
||||
exclude { file ->
|
||||
if (file.name.contains(".distanthorizons.accesswidener") && file.name != "${accessWidenerVersion}.distanthorizons.accesswidener") {
|
||||
return true
|
||||
@@ -459,17 +455,10 @@ subprojects { p ->
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
// Run mergeJars when running build
|
||||
// TODO: Fix later
|
||||
// if (isMinecraftSubProject) {
|
||||
// build.finalizedBy(mergeJars)
|
||||
// assemble.finalizedBy(mergeJars)
|
||||
// }
|
||||
}
|
||||
|
||||
allprojects { p ->
|
||||
// Does the same as "p == project(":common") || p == project(":fabric") || p == project(":quilt") || p == project(":forge")"
|
||||
// Does the same as "p == project(":common") || p == project(":fabric") || p == project(":quilt") || p == project(":forge") || p == project("WhateverWeAddLaterOn")"
|
||||
// Useful later on so we dont have duplicated code
|
||||
def isMinecraftSubProject = p != project(":core") && p != project(":api")
|
||||
|
||||
@@ -484,8 +473,21 @@ allprojects { p ->
|
||||
// this is the text that appears at the top of the overview (home) page
|
||||
// and is used when bookmarking a page
|
||||
javadoc.title = rootProject.mod_name + "-" + project.name
|
||||
|
||||
|
||||
|
||||
// Some annotations arent "technically" part of the official java standard,
|
||||
// so we define it ourself here
|
||||
javadoc {
|
||||
configure( options ) {
|
||||
tags(
|
||||
'todo:X"',
|
||||
'apiNote:a:API Note:',
|
||||
'implSpec:a:Implementation Requirements:',
|
||||
'implNote:a:Implementation Note:'
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
repositories {
|
||||
// The central repo
|
||||
mavenCentral()
|
||||
@@ -550,6 +552,7 @@ allprojects { p ->
|
||||
includeGroup "forge-mod"
|
||||
}
|
||||
}
|
||||
// TODO: If neoforged is ever needed, should we use that, or call it a forge mod?
|
||||
}
|
||||
|
||||
// Adds some dependencies that are in vanilla but not in core
|
||||
@@ -559,6 +562,7 @@ allprojects { p ->
|
||||
// Set the OS lwjgl is using to the current os
|
||||
project.ext.lwjglNatives = "natives-" + os.toFamilyName()
|
||||
|
||||
// TODO: Include Minecraft in core-projects but dont include MC code stuff
|
||||
dependencies { // All of these dependencies are in Vanilla Minecraft, but we need to depend on it as we arent importing Minecraft in the core
|
||||
// Imports most of lwjgl's libraries (well, only the ones that we need)
|
||||
implementation platform("org.lwjgl:lwjgl-bom:${rootProject.lwjgl_version}") // TODO: Use Minecraft's version for lwjgl_version (which changes in nearly every version) instead of a hard defined version for all versions
|
||||
@@ -591,26 +595,22 @@ allprojects { p ->
|
||||
}
|
||||
|
||||
|
||||
// TODO: Remove this as no loader needs this
|
||||
// - Fabric can rename which aw they use
|
||||
// - (Neo)Forge converts the aw to their own at, which is stored at a different place
|
||||
task copyCommonLoaderResources(type: Copy) {
|
||||
from project(":common").file("src/main/resources/${accessWidenerVersion}.distanthorizons.accesswidener")
|
||||
into(file(p.file("build/resources/main")))
|
||||
rename "${accessWidenerVersion}.distanthorizons.accesswidener", "distanthorizons.accesswidener"
|
||||
|
||||
|
||||
// Move the fabricLike mixin to its different places for each subproject
|
||||
if (findProject(":fabricLike")) {
|
||||
from project(":fabricLike").file("src/main/resources/DistantHorizons.fabricLike.mixins.json")
|
||||
into(file(p.file("build/resources/main")))
|
||||
rename "DistantHorizons.fabricLike.mixins.json", "DistantHorizons." + p.name + ".fabricLike.mixins.json"
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Remove this later as we no longer need this. We are now including the resources in the processResources section
|
||||
task copyCoreResources(type: Copy) {
|
||||
from fileTree(project(":core").file("src/main/resources"))
|
||||
into p.file("build/resources/main")
|
||||
}
|
||||
|
||||
tasks.withType(JavaCompile) {
|
||||
compileJava {
|
||||
if (isMinecraftSubProject) {
|
||||
options.release = rootProject.java_version as Integer
|
||||
options.compilerArgs += ["-Xplugin:Manifold"]
|
||||
|
||||
@@ -0,0 +1,239 @@
|
||||
import java.io.*;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URI;
|
||||
import java.net.URL;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class AWToAT {
|
||||
private static final Map<String, String> ACCESS_POINT_MAP = new HashMap<>();
|
||||
|
||||
static {
|
||||
ACCESS_POINT_MAP.put("accessible", "public");
|
||||
ACCESS_POINT_MAP.put("extendable", "public-f");
|
||||
ACCESS_POINT_MAP.put("mutable", "public-f");
|
||||
}
|
||||
|
||||
public String minecraftVersion;
|
||||
|
||||
public File remap(File file, String minecraftVersion) {
|
||||
this.minecraftVersion = minecraftVersion.replace("_", ".");
|
||||
File atFile = createATFile(file);
|
||||
processFile(file, atFile);
|
||||
return atFile;
|
||||
}
|
||||
|
||||
private File createATFile(File file) {
|
||||
File metaInf = new File(file.getParentFile(), "META-INF");
|
||||
if (!metaInf.exists() && !metaInf.mkdir()) throw new RuntimeException("Error creating META-INF folder");
|
||||
File atFile = new File(metaInf, "accesstransformer.cfg");
|
||||
try {
|
||||
atFile.createNewFile();
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("Error creating new file", e);
|
||||
}
|
||||
return atFile;
|
||||
}
|
||||
|
||||
private void processFile(File file, File atFile) {
|
||||
/* Validates if we need to recreate the Access Transformer file if it's out of date */
|
||||
// Get the hash of the file
|
||||
String fileHash = getFileHash(file);
|
||||
try (Scanner atScanner = new Scanner(atFile)) {
|
||||
// Check if the AT file is up-to-date by comparing the hash of the file with the hash stored in the AT file
|
||||
boolean hashFound = false;
|
||||
while (atScanner.hasNextLine()) {
|
||||
String line = atScanner.nextLine();
|
||||
if (hashCheck(line, fileHash)) {
|
||||
hashFound = true;
|
||||
}
|
||||
}
|
||||
|
||||
// If the AT file is up-to-date, print a message and return
|
||||
if (hashFound) {
|
||||
System.out.println("Access Transformer file is already up to date.");
|
||||
return;
|
||||
}
|
||||
} catch (FileNotFoundException ignored) {
|
||||
// If the AT file does not exist, continue
|
||||
}
|
||||
|
||||
/* Creates the Access Transformer file */
|
||||
// Opens a scanner for reading the Access Widener file and a writer for writing to the Access Transformer file
|
||||
try (Scanner scanner = new Scanner(file); FileWriter writer = new FileWriter(atFile)) {
|
||||
// Create an ExecutorService with a fixed thread pool size equal to the number of available processors
|
||||
ExecutorService executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
|
||||
// List to hold Future objects representing results of computation
|
||||
List<Future<String>> futures = new ArrayList<>();
|
||||
|
||||
// Write the hash of the file to the AT file
|
||||
writer.write("#DH_MAPPING_HASH:" + fileHash + "\n");
|
||||
|
||||
// Read each line from the file
|
||||
while (scanner.hasNextLine()) {
|
||||
String line = scanner.nextLine();
|
||||
// Skip lines starting with "accessWidener", "#" or blank lines
|
||||
if (line.startsWith("accessWidener") || line.startsWith("#") || line.isBlank()) continue;
|
||||
|
||||
// Submit the line to the executor service for processing
|
||||
// The processing is done by the processLine method
|
||||
futures.add(executor.submit(() -> processLine(line.split(" "))));
|
||||
}
|
||||
|
||||
// Write the results to the output file
|
||||
// The results are obtained by calling the get method on each Future
|
||||
for (Future<String> future : futures) {
|
||||
writer.write(future.get());
|
||||
}
|
||||
|
||||
// Shutdown the executor service to free up resources
|
||||
executor.shutdown();
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Error reading or writing to file", e);
|
||||
}
|
||||
}
|
||||
|
||||
private String processLine(String[] fields) {
|
||||
// fields[0] = access point like "accessible", "extendable", "mutable"
|
||||
// fields[1] = type like "field", "method", "class"
|
||||
// fields[2] = class name
|
||||
// fields[3] = field/method name
|
||||
// fields[4] = field/method descriptor
|
||||
|
||||
try {
|
||||
// Store the original field/method name
|
||||
String originalName = "";
|
||||
|
||||
// If there is a class name, replace the slashes with dots in the package name
|
||||
if (fields.length > 2) fields[2] = fields[2].replace("/", ".");
|
||||
|
||||
// If there is a field/method name, store the original name and remap it to SRG
|
||||
if (fields.length > 3) {
|
||||
originalName = fields[3];
|
||||
fields[3] = remapToSRG(fields[2], fields[3]);
|
||||
}
|
||||
|
||||
StringBuilder line = new StringBuilder(ACCESS_POINT_MAP.getOrDefault(fields[0], "public")).append(" ");
|
||||
switch (fields[1]) {
|
||||
case "field":
|
||||
line.append(fields[2]).append(" ").append(fields[3]).append(" #").append(originalName);
|
||||
// It'll be like: access-point class-name field-name-SRG # field-name-Mojmap
|
||||
// Eg: public net.minecraft.client.Minecraft f_90981_ # instance
|
||||
break;
|
||||
case "method":
|
||||
line.append(fields[2]).append(" ").append(fields[3]).append(fields[4]).append(" #").append(originalName);
|
||||
// It'll be like: access-point class-name method-name-SRG method-descriptor # method-name-Mojmap
|
||||
// Eg: public net.minecraft.client.Minecraft m_172797_()Lnet/minecraft/client/Minecraft; # getInstance
|
||||
break;
|
||||
default:
|
||||
line.append(fields[2]);
|
||||
// It'll be like: access-point class-name
|
||||
// Eg: public net.minecraft.client.Minecraft
|
||||
break;
|
||||
}
|
||||
line.append("\n");
|
||||
return line.toString();
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Error processing line", e);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean hashCheck(String line, String fileHash) {
|
||||
if (line.startsWith("#DH_MAPPING_HASH:")) {
|
||||
String hash = line.substring(17);
|
||||
return hash.equals(fileHash);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public String getFileHash(File file) {
|
||||
try {
|
||||
MessageDigest shaDigest = MessageDigest.getInstance("SHA-256");
|
||||
try (InputStream fis = new FileInputStream(file)) {
|
||||
byte[] byteArray = new byte[1024];
|
||||
int bytesCount;
|
||||
|
||||
// Read file data and update in message digest
|
||||
while ((bytesCount = fis.read(byteArray)) != -1) {
|
||||
shaDigest.update(byteArray, 0, bytesCount);
|
||||
}
|
||||
}
|
||||
|
||||
byte[] bytes = shaDigest.digest();
|
||||
|
||||
// Convert byte array into signum representation
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (byte aByte : bytes) {
|
||||
sb.append(Integer.toString((aByte & 0xff) + 0x100, 16).substring(1));
|
||||
}
|
||||
|
||||
// Return complete hash
|
||||
return sb.toString();
|
||||
} catch (NoSuchAlgorithmException | IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// WARNING: BELOW LIES HIGHLY CURSED CODE AND MIGHT EVEN BE ILLEGAL
|
||||
|
||||
|
||||
|
||||
|
||||
// Flag to track if there was an error in the GET request
|
||||
boolean error = false;
|
||||
|
||||
/**
|
||||
* This method returns a field or method name from Mojang mappings as SRG mappings.
|
||||
* It makes a GET request to the Linkie API to fetch the SRG name.
|
||||
*
|
||||
* @param clazz The class name
|
||||
* @param name The field or method name
|
||||
* @return The SRG name
|
||||
* @throws Exception If there is an error in the GET request or the SRG name is not found in the response
|
||||
*/
|
||||
private String remapToSRG(String clazz, String name) throws Exception {
|
||||
// Encode the class and field/method name to be used in the URL
|
||||
String query = URLEncoder.encode(clazz + "." + name, StandardCharsets.UTF_8);
|
||||
// Construct the URL for the GET request
|
||||
String urlString = "https://linkieapi.shedaniel.me/api/search?namespace=mojang&query=" + query + "&version=" + this.minecraftVersion + "&limit=1&allowClasses=false&allowFields=true&allowMethods=true&translate=mojang_srg";
|
||||
URL url = new URI(urlString).toURL();
|
||||
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
|
||||
conn.setRequestMethod("GET");
|
||||
int responseCode = conn.getResponseCode();
|
||||
if (responseCode == HttpURLConnection.HTTP_OK) {
|
||||
BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
|
||||
String inputLine;
|
||||
StringBuilder content = new StringBuilder();
|
||||
// Read the response line by line
|
||||
while ((inputLine = in.readLine()) != null) {
|
||||
content.append(inputLine);
|
||||
}
|
||||
in.close();
|
||||
conn.disconnect();
|
||||
// Regex to find the SRG name in the response
|
||||
Pattern pattern = Pattern.compile("\"l\"\\s*:\\s*\\{[^}]*\"i\"\\s*:\\s*\"([^\"]*)\"");
|
||||
Matcher matcher = pattern.matcher(content.toString());
|
||||
if (matcher.find()) return matcher.group(1);
|
||||
else throw new Exception("Couldn't find the SRG mapping for name: " + name + "\nCould not find 'i' in 'l' object in the response"); // `i` is the SRG name which is stored in the `l` JSON object
|
||||
} else {
|
||||
if (error) {
|
||||
// If there was an error in the GET request, and we already tried again, throw an exception
|
||||
throw new Exception("The GET request failed");
|
||||
}
|
||||
// If there was an error in the GET request, wait 2.5 seconds and try again as we probably got rate limited
|
||||
error = true;
|
||||
Thread.sleep(2500);
|
||||
return remapToSRG(clazz, name);
|
||||
}
|
||||
}
|
||||
}
|
||||
+12
-28
@@ -1,32 +1,16 @@
|
||||
plugins {
|
||||
id "org.spongepowered.gradle.vanilla" version "0.2.1-SNAPSHOT"
|
||||
}
|
||||
// Use Unimined's implimentation for MC as we can use Parchment mappings in common now! :tada:
|
||||
// With Sponge's vanilla gradle, we cannot change the mappings to anything out of mojmaps
|
||||
unimined.minecraft {
|
||||
fabric { // TODO: Find a way to only include the mc stuff, not fabric's loader
|
||||
loader rootProject.fabric_loader_version
|
||||
accessWidener(project(":common").file("src/main/resources/${accessWidenerVersion}.distanthorizons.accesswidener"))
|
||||
|
||||
minecraft {
|
||||
accessWideners(project(":common").file("src/main/resources/${accessWidenerVersion}.distanthorizons.accesswidener"))
|
||||
version(rootProject.minecraft_version)
|
||||
skipInsertAw = true
|
||||
}
|
||||
|
||||
defaultRemapJar = false
|
||||
}
|
||||
|
||||
dependencies {
|
||||
// We depend on fabric loader here to use the fabric @Environment annotations and get the mixin dependencies
|
||||
// Do NOT use other classes from fabric loader
|
||||
// modImplementation "net.fabricmc:fabric-loader:${rootProject.fabric_loader_version}"
|
||||
|
||||
// So mixins can be written in common
|
||||
compileOnly group:'org.spongepowered', name:'mixin', version:'0.8.5'
|
||||
}
|
||||
|
||||
|
||||
publishing {
|
||||
publications {
|
||||
mavenCommon(MavenPublication) {
|
||||
artifactId = rootProject.mod_readable_name
|
||||
from components.java
|
||||
}
|
||||
}
|
||||
|
||||
// See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing.
|
||||
repositories {
|
||||
// Add repositories to publish to here.
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,185 @@
|
||||
package com.seibel.distanthorizons.common;
|
||||
|
||||
import com.mojang.brigadier.CommandDispatcher;
|
||||
import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiAfterDhInitEvent;
|
||||
import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiBeforeDhInitEvent;
|
||||
import com.seibel.distanthorizons.common.wrappers.DependencySetup;
|
||||
import com.seibel.distanthorizons.common.wrappers.minecraft.MinecraftDedicatedServerWrapper;
|
||||
import com.seibel.distanthorizons.core.api.internal.SharedApi;
|
||||
import com.seibel.distanthorizons.core.config.Config;
|
||||
import com.seibel.distanthorizons.core.config.ConfigBase;
|
||||
import com.seibel.distanthorizons.core.config.eventHandlers.presets.ThreadPresetConfigEventHandler;
|
||||
import com.seibel.distanthorizons.core.dependencyInjection.ModAccessorInjector;
|
||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||
import com.seibel.distanthorizons.core.jar.ModJarInfo;
|
||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IModAccessor;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IModChecker;
|
||||
import com.seibel.distanthorizons.coreapi.DependencyInjection.ApiEventInjector;
|
||||
import com.seibel.distanthorizons.coreapi.ModInfo;
|
||||
import net.minecraft.commands.CommandSourceStack;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.dedicated.DedicatedServer;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
* Base for all mod loader initializers
|
||||
* and handles most setup.
|
||||
*/
|
||||
public abstract class AbstractModInitializer
|
||||
{
|
||||
protected static final Logger LOGGER = DhLoggerBuilder.getLogger(MethodHandles.lookup().lookupClass().getSimpleName());
|
||||
|
||||
private CommandDispatcher<CommandSourceStack> commandDispatcher;
|
||||
|
||||
|
||||
|
||||
//==================//
|
||||
// abstract methods //
|
||||
//==================//
|
||||
|
||||
protected abstract void createInitialBindings();
|
||||
protected abstract IEventProxy createClientProxy();
|
||||
protected abstract IEventProxy createServerProxy(boolean isDedicated);
|
||||
protected abstract void initializeModCompat();
|
||||
|
||||
protected abstract void subscribeRegisterCommandsEvent(Consumer<CommandDispatcher<CommandSourceStack>> eventHandler);
|
||||
|
||||
protected abstract void subscribeClientStartedEvent(Runnable eventHandler);
|
||||
protected abstract void subscribeServerStartingEvent(Consumer<MinecraftServer> eventHandler);
|
||||
protected abstract void runDelayedSetup();
|
||||
|
||||
|
||||
|
||||
//===================//
|
||||
// initialize events //
|
||||
//===================//
|
||||
|
||||
public void onInitializeClient()
|
||||
{
|
||||
DependencySetup.createClientBindings();
|
||||
|
||||
LOGGER.info("Initializing " + ModInfo.READABLE_NAME);
|
||||
ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeDhInitEvent.class, null);
|
||||
|
||||
this.startup();
|
||||
this.printModInfo(true);
|
||||
|
||||
this.createClientProxy().registerEvents();
|
||||
this.createServerProxy(false).registerEvents();
|
||||
|
||||
this.initializeModCompat();
|
||||
|
||||
LOGGER.info(ModInfo.READABLE_NAME + " Initialized");
|
||||
ApiEventInjector.INSTANCE.fireAllEvents(DhApiAfterDhInitEvent.class, null);
|
||||
|
||||
// Client uses config for auto-updater, so it's initialized here instead of post-init stage
|
||||
this.initConfig();
|
||||
|
||||
this.subscribeClientStartedEvent(this::postInit);
|
||||
}
|
||||
|
||||
public void onInitializeServer()
|
||||
{
|
||||
DependencySetup.createServerBindings();
|
||||
|
||||
LOGGER.info("Initializing " + ModInfo.READABLE_NAME);
|
||||
ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeDhInitEvent.class, null);
|
||||
|
||||
this.startup();
|
||||
this.printModInfo(false);
|
||||
|
||||
// This prevents returning uninitialized Config values,
|
||||
// resulting from a circular reference mid-initialization in a static class
|
||||
// noinspection ResultOfMethodCallIgnored
|
||||
ThreadPresetConfigEventHandler.INSTANCE.toString();
|
||||
|
||||
this.createServerProxy(true).registerEvents();
|
||||
|
||||
LOGGER.info(ModInfo.READABLE_NAME + " Initialized");
|
||||
ApiEventInjector.INSTANCE.fireAllEvents(DhApiAfterDhInitEvent.class, null);
|
||||
|
||||
this.subscribeRegisterCommandsEvent(dispatcher -> { this.commandDispatcher = dispatcher; });
|
||||
|
||||
this.subscribeServerStartingEvent(server ->
|
||||
{
|
||||
MinecraftDedicatedServerWrapper.INSTANCE.dedicatedServer = (DedicatedServer)server;
|
||||
|
||||
this.initConfig();
|
||||
this.postInit();
|
||||
this.initCommands();
|
||||
|
||||
LOGGER.info("Dedicated server initialized at " + server.getServerDirectory());
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
//===========================//
|
||||
// inner initializer methods //
|
||||
//===========================//
|
||||
|
||||
private void startup()
|
||||
{
|
||||
DependencySetup.createSharedBindings();
|
||||
SharedApi.init();
|
||||
this.createInitialBindings();
|
||||
}
|
||||
|
||||
private void printModInfo(boolean printGitInfo)
|
||||
{
|
||||
LOGGER.info(ModInfo.READABLE_NAME + ", Version: " + ModInfo.VERSION);
|
||||
|
||||
if (printGitInfo)
|
||||
{
|
||||
// Useful for dev builds
|
||||
LOGGER.info("DH Branch: " + ModJarInfo.Git_Branch);
|
||||
LOGGER.info("DH Commit: " + ModJarInfo.Git_Commit);
|
||||
LOGGER.info("DH Jar Build Source: " + ModJarInfo.Build_Source);
|
||||
}
|
||||
}
|
||||
|
||||
protected <T extends IModAccessor> void tryCreateModCompatAccessor(String modId, Class<? super T> accessorClass, Supplier<T> accessorConstructor)
|
||||
{
|
||||
IModChecker modChecker = SingletonInjector.INSTANCE.get(IModChecker.class);
|
||||
if (modChecker.isModLoaded(modId))
|
||||
{
|
||||
//noinspection unchecked
|
||||
ModAccessorInjector.INSTANCE.bind((Class<? extends IModAccessor>) accessorClass, accessorConstructor.get());
|
||||
}
|
||||
}
|
||||
|
||||
private void initConfig()
|
||||
{
|
||||
ConfigBase.INSTANCE = new ConfigBase(ModInfo.ID, ModInfo.NAME, Config.class, 2);
|
||||
Config.completeDelayedSetup();
|
||||
}
|
||||
|
||||
private void postInit()
|
||||
{
|
||||
LOGGER.info("Post-Initializing Mod");
|
||||
this.runDelayedSetup();
|
||||
LOGGER.info("Mod Post-Initialized");
|
||||
}
|
||||
|
||||
private void initCommands()
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
|
||||
|
||||
//================//
|
||||
// helper classes //
|
||||
//================//
|
||||
|
||||
public interface IEventProxy
|
||||
{
|
||||
void registerEvents();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
/*
|
||||
* This file is part of the Distant Horizons mod
|
||||
* licensed under the GNU LGPL v3 License.
|
||||
*
|
||||
* Copyright (C) 2020-2023 James Seibel
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.seibel.distanthorizons.common;
|
||||
|
||||
import com.seibel.distanthorizons.common.forge.LodForgeMethodCaller;
|
||||
import com.seibel.distanthorizons.common.wrappers.DependencySetup;
|
||||
import com.seibel.distanthorizons.coreapi.ModInfo;
|
||||
import com.seibel.distanthorizons.core.api.internal.SharedApi;
|
||||
import com.seibel.distanthorizons.core.config.Config;
|
||||
import com.seibel.distanthorizons.core.config.ConfigBase;
|
||||
|
||||
/**
|
||||
* This is the common main class
|
||||
*
|
||||
* @author Ran
|
||||
*/
|
||||
public class LodCommonMain
|
||||
{
|
||||
public static boolean forge = false;
|
||||
public static LodForgeMethodCaller forgeMethodCaller;
|
||||
|
||||
|
||||
|
||||
public static void startup(LodForgeMethodCaller forgeMethodCaller)
|
||||
{
|
||||
if (forgeMethodCaller != null)
|
||||
{
|
||||
LodCommonMain.forge = true;
|
||||
LodCommonMain.forgeMethodCaller = forgeMethodCaller;
|
||||
}
|
||||
|
||||
DependencySetup.createSharedBindings();
|
||||
SharedApi.init();
|
||||
// if (!serverSided) {
|
||||
// new NetworkReceiver().register_Client();
|
||||
// } else {
|
||||
// new NetworkReceiver().register_Server();
|
||||
// }
|
||||
}
|
||||
|
||||
public static void initConfig()
|
||||
{
|
||||
ConfigBase.INSTANCE = new ConfigBase(ModInfo.ID, ModInfo.NAME, Config.class, 1);
|
||||
Config.completeDelayedSetup();
|
||||
}
|
||||
|
||||
}
|
||||
-52
@@ -1,52 +0,0 @@
|
||||
/*
|
||||
* This file is part of the Distant Horizons mod
|
||||
* licensed under the GNU LGPL v3 License.
|
||||
*
|
||||
* Copyright (C) 2020-2023 James Seibel
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.seibel.distanthorizons.common.forge;
|
||||
|
||||
import com.seibel.distanthorizons.common.wrappers.minecraft.MinecraftClientWrapper;
|
||||
import net.minecraft.client.renderer.block.model.BakedQuad;
|
||||
import net.minecraft.core.Direction;
|
||||
#if POST_MC_1_19_2
|
||||
import net.minecraft.util.RandomSource;
|
||||
#endif
|
||||
import net.minecraft.world.level.ColorResolver;
|
||||
import net.minecraft.world.level.biome.Biome;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* used for calling methods that forge modified
|
||||
* (forge modifies vanilla methods for some reason)
|
||||
*
|
||||
* @author Ran
|
||||
*/
|
||||
public interface LodForgeMethodCaller
|
||||
{
|
||||
#if PRE_MC_1_19_2
|
||||
List<BakedQuad> getQuads(MinecraftClientWrapper mc, Block block, BlockState blockState, Direction direction, Random random); // FIXME: For 1.19
|
||||
#else
|
||||
List<BakedQuad> getQuads(MinecraftClientWrapper mc, Block block, BlockState blockState, Direction direction, RandomSource random); // FIXME: For 1.19
|
||||
#endif
|
||||
|
||||
int colorResolverGetColor(ColorResolver resolver, Biome biome, double x, double z);
|
||||
|
||||
}
|
||||
+2
-4
@@ -19,11 +19,9 @@
|
||||
|
||||
package com.seibel.distanthorizons.common.rendering;
|
||||
|
||||
#if PRE_MC_1_19_4
|
||||
|
||||
#if MC_VER < MC_1_19_4
|
||||
import com.mojang.math.Matrix4f;
|
||||
#else
|
||||
|
||||
import org.joml.Matrix4f;
|
||||
#endif
|
||||
import com.seibel.distanthorizons.core.config.Config;
|
||||
@@ -43,7 +41,7 @@ public class SeamlessOverdraw
|
||||
{
|
||||
float[] matrixFloatArray;
|
||||
|
||||
#if PRE_MC_1_19_4
|
||||
#if MC_VER < MC_1_19_4
|
||||
FloatBuffer matrixFloatBuffer = FloatBuffer.allocate(16);
|
||||
minecraftProjectionMatrix.store(matrixFloatBuffer);
|
||||
matrixFloatArray = matrixFloatBuffer.array();
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* This file is part of the Distant Horizons mod
|
||||
* licensed under the GNU LGPL v3 License.
|
||||
*
|
||||
* Copyright (C) 2020-2023 James Seibel
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.seibel.distanthorizons.common.util;
|
||||
|
||||
/**
|
||||
* Added to MC's dynamic textures via mixins
|
||||
* in order to denote whether a texture is a lightmap or not. <br><br>
|
||||
*
|
||||
* If not done any dynamic texture could be used as the lightmap
|
||||
* which causes some weird rendering bugs.
|
||||
*/
|
||||
public interface ILightTextureMarker
|
||||
{
|
||||
void markLightTexture();
|
||||
}
|
||||
+24
-21
@@ -23,12 +23,6 @@ import java.nio.FloatBuffer;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
#if PRE_MC_1_19_4
|
||||
import com.mojang.math.Matrix4f;
|
||||
#else
|
||||
import org.joml.Matrix4f;
|
||||
#endif
|
||||
|
||||
import com.seibel.distanthorizons.core.enums.EDhDirection;
|
||||
import com.seibel.distanthorizons.core.pos.DhBlockPos;
|
||||
import com.seibel.distanthorizons.core.pos.DhChunkPos;
|
||||
@@ -51,10 +45,31 @@ public class McObjectConverter
|
||||
{
|
||||
return y * 4 + x;
|
||||
}
|
||||
/** Taken from Minecraft's com.mojang.math.Matrix4f class from 1.18.2 */
|
||||
private static void storeMatrix(Matrix4f matrix, FloatBuffer buffer)
|
||||
|
||||
|
||||
/** 4x4 float matrix converter */
|
||||
@Deprecated
|
||||
public static Mat4f Convert(
|
||||
#if MC_VER < MC_1_19_4 com.mojang.math.Matrix4f
|
||||
#else org.joml.Matrix4f #endif
|
||||
mcMatrix)
|
||||
{
|
||||
#if PRE_MC_1_19_4
|
||||
FloatBuffer buffer = FloatBuffer.allocate(16);
|
||||
storeMatrix(mcMatrix, buffer);
|
||||
Mat4f matrix = new Mat4f(buffer);
|
||||
#if MC_VER < MC_1_19_4
|
||||
matrix.transpose(); // In 1.19.3 and later, we no longer need to transpose it
|
||||
#endif
|
||||
return matrix;
|
||||
}
|
||||
/** Taken from Minecraft's com.mojang.math.Matrix4f class from 1.18.2 */
|
||||
private static void storeMatrix(
|
||||
#if MC_VER < MC_1_19_4 com.mojang.math.Matrix4f
|
||||
#else org.joml.Matrix4f #endif
|
||||
matrix,
|
||||
FloatBuffer buffer)
|
||||
{
|
||||
#if MC_VER < MC_1_19_4
|
||||
matrix.store(buffer);
|
||||
#else
|
||||
// Mojang starts to use joml's Matrix4f libary in 1.19.3 so we copy their store method and use it here if its newer than 1.19.3
|
||||
@@ -77,18 +92,6 @@ public class McObjectConverter
|
||||
#endif
|
||||
}
|
||||
|
||||
/** 4x4 float matrix converter */
|
||||
public static Mat4f Convert(Matrix4f mcMatrix)
|
||||
{
|
||||
FloatBuffer buffer = FloatBuffer.allocate(16);
|
||||
storeMatrix(mcMatrix, buffer);
|
||||
Mat4f matrix = new Mat4f(buffer);
|
||||
#if PRE_MC_1_19_4
|
||||
matrix.transpose(); // In 1.19.3 and later, we no longer need to transpose it
|
||||
#endif
|
||||
return matrix;
|
||||
}
|
||||
|
||||
|
||||
static final Direction[] directions;
|
||||
static final EDhDirection[] lodDirections;
|
||||
|
||||
+1
-1
@@ -59,7 +59,7 @@ public class VersionConstants implements IVersionConstants
|
||||
@Override
|
||||
public String getMinecraftVersion()
|
||||
{
|
||||
#if PRE_MC_1_19_2
|
||||
#if MC_VER < MC_1_19_2
|
||||
return Minecraft.getInstance().getGame().getVersion().getId();
|
||||
#else
|
||||
return SharedConstants.getCurrentVersion().getId();
|
||||
|
||||
+165
-12
@@ -19,7 +19,11 @@
|
||||
|
||||
package com.seibel.distanthorizons.common.wrappers;
|
||||
|
||||
import com.seibel.distanthorizons.api.interfaces.block.IDhApiBiomeWrapper;
|
||||
import com.seibel.distanthorizons.api.interfaces.block.IDhApiBlockStateWrapper;
|
||||
import com.seibel.distanthorizons.api.interfaces.override.worldGenerator.IDhApiWorldGenerator;
|
||||
import com.seibel.distanthorizons.api.interfaces.world.IDhApiLevelWrapper;
|
||||
import com.seibel.distanthorizons.api.interfaces.factories.IDhApiWrapperFactory;
|
||||
import com.seibel.distanthorizons.common.wrappers.block.BiomeWrapper;
|
||||
import com.seibel.distanthorizons.common.wrappers.block.BlockStateWrapper;
|
||||
import com.seibel.distanthorizons.common.wrappers.chunk.ChunkWrapper;
|
||||
@@ -35,9 +39,14 @@ import com.seibel.distanthorizons.core.wrapperInterfaces.world.IBiomeWrapper;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.worldGeneration.AbstractBatchGenerationEnvironmentWrapper;
|
||||
import net.minecraft.client.multiplayer.ClientLevel;
|
||||
#if MC_VER > MC_1_17_1
|
||||
import net.minecraft.core.Holder;
|
||||
#endif
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.LevelReader;
|
||||
import net.minecraft.world.level.biome.Biome;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.chunk.ChunkAccess;
|
||||
|
||||
import java.io.IOException;
|
||||
@@ -55,6 +64,9 @@ public class WrapperFactory implements IWrapperFactory
|
||||
|
||||
|
||||
|
||||
//==============//
|
||||
// core methods //
|
||||
//==============//
|
||||
|
||||
@Override
|
||||
public AbstractBatchGenerationEnvironmentWrapper createBatchGenerator(IDhLevel targetLevel)
|
||||
@@ -106,8 +118,7 @@ public class WrapperFactory implements IWrapperFactory
|
||||
}
|
||||
}
|
||||
|
||||
// MC 1.16, 1.18, 1.19, 1.20
|
||||
#if POST_MC_1_17_1 || MC_1_16_5
|
||||
#if MC_VER <= MC_1_20_4
|
||||
else if (objectArray.length == 2)
|
||||
{
|
||||
// correct number of parameters from the API
|
||||
@@ -156,7 +167,7 @@ public class WrapperFactory implements IWrapperFactory
|
||||
#else
|
||||
// Intentional compiler error to bring attention to the missing wrapper function.
|
||||
// If you need to work on an unimplemented version but don't have the ability to implement this yet
|
||||
// you can comment it out, but please don't commit it. Someone will have to implement it .
|
||||
// you can comment it out, but please don't commit it. Someone will have to implement it.
|
||||
|
||||
// After implementing the new version please read this method's javadocs for instructions
|
||||
// on what other locations also need to be updated, the DhAPI specifically needs to
|
||||
@@ -170,25 +181,167 @@ public class WrapperFactory implements IWrapperFactory
|
||||
*/
|
||||
private static String createChunkWrapperErrorMessage(Object[] objectArray)
|
||||
{
|
||||
StringBuilder message = new StringBuilder(
|
||||
"Chunk wrapper creation failed. \n" +
|
||||
"Expected parameters: \n");
|
||||
String[] expectedClassNames;
|
||||
|
||||
// MC 1.16, 1.18, 1.19, 1.20
|
||||
#if POST_MC_1_17_1 || MC_1_16_5
|
||||
message.append("[" + ChunkAccess.class.getName() + "], \n");
|
||||
message.append("[" + ServerLevel.class.getName() + "] or [" + ClientLevel.class.getName() + "]. \n");
|
||||
#if MC_VER <= MC_1_20_4
|
||||
expectedClassNames = new String[]
|
||||
{
|
||||
ChunkAccess.class.getName(),
|
||||
ServerLevel.class.getName() + "] or [" + ClientLevel.class.getName()
|
||||
};
|
||||
#else
|
||||
// See preprocessor comment in createChunkWrapper() for full documentation
|
||||
not implemented for this version of Minecraft!
|
||||
#endif
|
||||
|
||||
return createWrapperErrorMessage("Chunk wrapper", expectedClassNames, objectArray);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//=============//
|
||||
// api methods //
|
||||
//=============//
|
||||
|
||||
// documentation should be in the API interface
|
||||
|
||||
public IDhApiBiomeWrapper getBiomeWrapper(Object[] objectArray, IDhApiLevelWrapper levelWrapper)
|
||||
{
|
||||
// confirm the API level wrapper is also a Core wrapper
|
||||
if (!(levelWrapper instanceof ILevelWrapper))
|
||||
{
|
||||
throw new ClassCastException("Unable to cast... only DH provided IDhApiLevelWrapper's can be used."); // TODO
|
||||
}
|
||||
ILevelWrapper coreLevelWrapper = (ILevelWrapper) levelWrapper;
|
||||
|
||||
|
||||
|
||||
#if MC_VER < MC_1_20_4
|
||||
if (objectArray.length != 1)
|
||||
{
|
||||
throw new ClassCastException(createBiomeWrapperErrorMessage(objectArray));
|
||||
}
|
||||
#endif
|
||||
|
||||
#if MC_VER < MC_1_18_2
|
||||
if (!(objectArray[0] instanceof Biome))
|
||||
{
|
||||
throw new ClassCastException(createBiomeWrapperErrorMessage(objectArray));
|
||||
}
|
||||
|
||||
Biome biome = (Biome) objectArray[0];
|
||||
return BiomeWrapper.getBiomeWrapper(biome, coreLevelWrapper);
|
||||
#elif MC_VER <= MC_1_20_4
|
||||
if (!(objectArray[0] instanceof Holder) || !(((Holder<?>) objectArray[0]).value() instanceof Biome))
|
||||
{
|
||||
throw new ClassCastException(createBiomeWrapperErrorMessage(objectArray));
|
||||
}
|
||||
|
||||
Holder<Biome> biomeHolder = (Holder<Biome>) objectArray[0];
|
||||
return BiomeWrapper.getBiomeWrapper(biomeHolder, coreLevelWrapper);
|
||||
#else
|
||||
// See preprocessor comment in createChunkWrapper() for full documentation (not a typo, check createChunkWrapper()'s else statement for full documentation)
|
||||
not implemented for this version of Minecraft!
|
||||
#endif
|
||||
}
|
||||
/**
|
||||
* Note: when this is updated for different MC versions,
|
||||
* make sure you also update the documentation in {@link IDhApiWrapperFactory#getBiomeWrapper}.
|
||||
*/
|
||||
private static String createBiomeWrapperErrorMessage(Object[] objectArray)
|
||||
{
|
||||
String[] expectedClassNames;
|
||||
|
||||
#if MC_VER < MC_1_18_2
|
||||
expectedClassNames = new String[] { Biome.class.getName() };
|
||||
#elif MC_VER <= MC_1_20_4
|
||||
expectedClassNames = new String[] { Holder.class.getName()+"<"+Biome.class.getName()+">" };
|
||||
#else
|
||||
// See preprocessor comment in createChunkWrapper() for full documentation
|
||||
not implemented for this version of Minecraft!
|
||||
#endif
|
||||
|
||||
return createWrapperErrorMessage("Biome wrapper", expectedClassNames, objectArray);
|
||||
}
|
||||
|
||||
public IDhApiBlockStateWrapper getBlockStateWrapper(Object[] objectArray, IDhApiLevelWrapper levelWrapper)
|
||||
{
|
||||
// confirm the API level wrapper is also a Core wrapper
|
||||
if (!(levelWrapper instanceof ILevelWrapper))
|
||||
{
|
||||
throw new ClassCastException("Unable to cast... only DH provided IDhApiLevelWrapper's can be used."); // TODO
|
||||
}
|
||||
ILevelWrapper coreLevelWrapper = (ILevelWrapper) levelWrapper;
|
||||
|
||||
|
||||
|
||||
#if MC_VER <= MC_1_20_4
|
||||
if (objectArray.length != 1)
|
||||
{
|
||||
throw new ClassCastException(createBlockStateWrapperErrorMessage(objectArray));
|
||||
}
|
||||
if (!(objectArray[0] instanceof BlockState))
|
||||
{
|
||||
throw new ClassCastException(createBlockStateWrapperErrorMessage(objectArray));
|
||||
}
|
||||
|
||||
BlockState blockState = (BlockState) objectArray[0];
|
||||
return BlockStateWrapper.fromBlockState(blockState, coreLevelWrapper);
|
||||
#else
|
||||
// See preprocessor comment in createChunkWrapper() for full documentation (not a typo, check createChunkWrapper()'s else statement for full documentation)
|
||||
not implemented for this version of Minecraft!
|
||||
#endif
|
||||
}
|
||||
/**
|
||||
* Note: when this is updated for different MC versions,
|
||||
* make sure you also update the documentation in {@link IDhApiWrapperFactory#getBlockStateWrapper}.
|
||||
*/
|
||||
private static String createBlockStateWrapperErrorMessage(Object[] objectArray)
|
||||
{
|
||||
String[] expectedClassNames;
|
||||
|
||||
#if MC_VER == MC_1_16_5 || MC_VER == MC_1_17_1
|
||||
expectedClassNames = new String[] { Biome.class.getName() };
|
||||
#elif MC_VER <= MC_1_20_4
|
||||
expectedClassNames = new String[] { Holder.class.getName()+"<"+Biome.class.getName()+">" };
|
||||
#else
|
||||
// See preprocessor comment in createChunkWrapper() for full documentation
|
||||
not implemented for this version of Minecraft!
|
||||
#endif
|
||||
|
||||
return createWrapperErrorMessage("BlockState wrapper", expectedClassNames, objectArray);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//================//
|
||||
// helper methods //
|
||||
//================//
|
||||
|
||||
private static String createWrapperErrorMessage(String wrapperName, String[] expectedClassNames, Object[] objectArray)
|
||||
{
|
||||
// error header
|
||||
StringBuilder message = new StringBuilder(
|
||||
wrapperName + " creation failed. \n" +
|
||||
"Expected object array parameters: \n");
|
||||
|
||||
|
||||
// expected parameters
|
||||
for (String expectedClassName : expectedClassNames)
|
||||
{
|
||||
message.append("[").append(expectedClassName).append("], \n");
|
||||
}
|
||||
|
||||
|
||||
// given parameters
|
||||
if (objectArray.length != 0)
|
||||
{
|
||||
message.append("Given parameters: ");
|
||||
for (Object obj : objectArray)
|
||||
{
|
||||
message.append("[").append(obj.getClass().getName()).append("], ");
|
||||
String objClassName = (obj != null) ? obj.getClass().getName() : "NULL";
|
||||
message.append("[").append(objClassName).append("], ");
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -196,8 +349,8 @@ public class WrapperFactory implements IWrapperFactory
|
||||
message.append(" No parameters given.");
|
||||
}
|
||||
|
||||
|
||||
return message.toString();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
+72
-50
@@ -33,18 +33,10 @@ import org.apache.logging.log4j.Logger;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IBiomeWrapper;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
#if POST_MC_1_17
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.resources.RegistryOps;
|
||||
#endif
|
||||
|
||||
#if POST_MC_1_19_2
|
||||
#endif
|
||||
|
||||
|
||||
#if MC_1_16_5 || MC_1_17_1
|
||||
#if MC_VER == MC_1_16_5 || MC_VER == MC_1_17_1
|
||||
import net.minecraft.core.Registry;
|
||||
#elif MC_1_18_2 || MC_1_19_2
|
||||
#elif MC_VER == MC_1_18_2 || MC_VER == MC_1_19_2
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.core.RegistryAccess;
|
||||
@@ -56,7 +48,7 @@ import net.minecraft.core.registries.Registries;
|
||||
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.level.biome.Biome;
|
||||
#if !PRE_MC_1_18_2
|
||||
#if MC_VER >= MC_1_18_2
|
||||
import net.minecraft.world.level.biome.Biomes;
|
||||
#endif
|
||||
|
||||
@@ -66,23 +58,30 @@ public class BiomeWrapper implements IBiomeWrapper
|
||||
{
|
||||
private static final Logger LOGGER = LogManager.getLogger();
|
||||
|
||||
#if PRE_MC_1_18_2
|
||||
#if MC_VER < MC_1_18_2
|
||||
public static final ConcurrentMap<Biome, BiomeWrapper> WRAPPER_BY_BIOME = new ConcurrentHashMap<>();
|
||||
#else
|
||||
public static final ConcurrentMap<Holder<Biome>, BiomeWrapper> WRAPPER_BY_BIOME = new ConcurrentHashMap<>();
|
||||
#endif
|
||||
|
||||
public static final String EMPTY_STRING = "EMPTY";
|
||||
public static final BiomeWrapper EMPTY_WRAPPER = new BiomeWrapper(null, null);
|
||||
public static final BiomeWrapper EMPTY_WRAPPER = new BiomeWrapper();
|
||||
|
||||
/** keep track of broken biomes so we don't log every time */
|
||||
private static final HashSet<String> BrokenResourceLocationStrings = new HashSet<>();
|
||||
private static final HashSet<String> brokenResourceLocationStrings = new HashSet<>();
|
||||
|
||||
/**
|
||||
* Only display this warning once, otherwise the log may be spammed <br>
|
||||
* This is a known issue when joining Hypixel.
|
||||
*/
|
||||
private static boolean emptyStringWarningLogged = false;
|
||||
private static boolean emptyLevelSerializeFailLogged = false;
|
||||
|
||||
|
||||
|
||||
// properties //
|
||||
|
||||
#if PRE_MC_1_18_2
|
||||
#if MC_VER < MC_1_18_2
|
||||
public final Biome biome;
|
||||
#else
|
||||
public final Holder<Biome> biome;
|
||||
@@ -97,7 +96,7 @@ public class BiomeWrapper implements IBiomeWrapper
|
||||
// constructors //
|
||||
//==============//
|
||||
|
||||
static public IBiomeWrapper getBiomeWrapper(#if PRE_MC_1_18_2 Biome #else Holder<Biome> #endif biome, ILevelWrapper levelWrapper)
|
||||
static public IBiomeWrapper getBiomeWrapper(#if MC_VER < MC_1_18_2 Biome #else Holder<Biome> #endif biome, ILevelWrapper levelWrapper)
|
||||
{
|
||||
if (biome == null)
|
||||
{
|
||||
@@ -116,14 +115,20 @@ public class BiomeWrapper implements IBiomeWrapper
|
||||
return newWrapper;
|
||||
}
|
||||
}
|
||||
|
||||
private BiomeWrapper(#if PRE_MC_1_18_2 Biome #else Holder<Biome> #endif biome, ILevelWrapper levelWrapper)
|
||||
private BiomeWrapper(#if MC_VER < MC_1_18_2 Biome #else Holder<Biome> #endif biome, ILevelWrapper levelWrapper)
|
||||
{
|
||||
this.biome = biome;
|
||||
this.serialString = this.serialize(levelWrapper);
|
||||
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_STRING;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//=========//
|
||||
@@ -138,7 +143,7 @@ public class BiomeWrapper implements IBiomeWrapper
|
||||
return EMPTY_STRING;
|
||||
}
|
||||
|
||||
#if PRE_MC_1_18_2
|
||||
#if MC_VER < MC_1_18_2
|
||||
return biome.toString();
|
||||
#else
|
||||
return this.biome.unwrapKey().orElse(Biomes.THE_VOID).registry().toString();
|
||||
@@ -182,42 +187,55 @@ public class BiomeWrapper implements IBiomeWrapper
|
||||
|
||||
public String serialize(ILevelWrapper levelWrapper)
|
||||
{
|
||||
if (this.serialString != null)
|
||||
{
|
||||
return this.serialString;
|
||||
}
|
||||
|
||||
|
||||
// we can't generate a serial string if the level is null
|
||||
if (levelWrapper == null)
|
||||
{
|
||||
if (!emptyLevelSerializeFailLogged)
|
||||
{
|
||||
emptyLevelSerializeFailLogged = true;
|
||||
LOGGER.warn("Unable to serialize biome: ["+this.biome+"] because the passed in level wrapper is null. Future errors won't be logged.");
|
||||
}
|
||||
|
||||
return EMPTY_STRING;
|
||||
}
|
||||
|
||||
|
||||
if (this.serialString == null)
|
||||
|
||||
// generate the serial string //
|
||||
|
||||
net.minecraft.core.RegistryAccess registryAccess = Minecraft.getInstance().level.registryAccess();
|
||||
|
||||
ResourceLocation resourceLocation;
|
||||
#if MC_VER == MC_1_16_5 || MC_VER == MC_1_17_1
|
||||
resourceLocation = registryAccess.registryOrThrow(Registry.BIOME_REGISTRY).getKey(this.biome);
|
||||
#elif MC_VER == MC_1_18_2 || MC_VER == MC_1_19_2
|
||||
resourceLocation = registryAccess.registryOrThrow(Registry.BIOME_REGISTRY).getKey(this.biome.value());
|
||||
#else
|
||||
resourceLocation = registryAccess.registryOrThrow(Registries.BIOME).getKey(this.biome.value());
|
||||
#endif
|
||||
|
||||
if (resourceLocation == null)
|
||||
{
|
||||
net.minecraft.core.RegistryAccess registryAccess = Minecraft.getInstance().level.registryAccess();
|
||||
|
||||
ResourceLocation resourceLocation;
|
||||
#if MC_1_16_5 || MC_1_17_1
|
||||
resourceLocation = registryAccess.registryOrThrow(Registry.BIOME_REGISTRY).getKey(this.biome);
|
||||
#elif MC_1_18_2 || MC_1_19_2
|
||||
resourceLocation = registryAccess.registryOrThrow(Registry.BIOME_REGISTRY).getKey(this.biome.value());
|
||||
String biomeName;
|
||||
#if MC_VER == MC_1_16_5 || MC_VER == MC_1_17_1
|
||||
biomeName = this.biome.toString();
|
||||
#else
|
||||
resourceLocation = registryAccess.registryOrThrow(Registries.BIOME).getKey(this.biome.value());
|
||||
biomeName = this.biome.value().toString();
|
||||
#endif
|
||||
|
||||
if (resourceLocation == null)
|
||||
{
|
||||
String biomeName;
|
||||
#if MC_1_16_5 || MC_1_17_1
|
||||
biomeName = this.biome.toString();
|
||||
#else
|
||||
biomeName = this.biome.value().toString();
|
||||
#endif
|
||||
|
||||
LOGGER.warn("unable to serialize: " + biomeName);
|
||||
// shouldn't normally happen, but just in case
|
||||
this.serialString = "";
|
||||
}
|
||||
else
|
||||
{
|
||||
this.serialString = resourceLocation.getNamespace() + ":" + resourceLocation.getPath();
|
||||
}
|
||||
LOGGER.warn("unable to serialize: " + biomeName);
|
||||
// shouldn't normally happen, but just in case
|
||||
this.serialString = "";
|
||||
}
|
||||
else
|
||||
{
|
||||
this.serialString = resourceLocation.getNamespace() + ":" + resourceLocation.getPath();
|
||||
}
|
||||
|
||||
return this.serialString;
|
||||
@@ -227,7 +245,11 @@ public class BiomeWrapper implements IBiomeWrapper
|
||||
{
|
||||
if (resourceLocationString.equals(EMPTY_STRING))
|
||||
{
|
||||
LOGGER.warn("["+EMPTY_STRING+"] biome string deserialized. This may mean there was a file saving error or a biome saving error.");
|
||||
if (!emptyStringWarningLogged)
|
||||
{
|
||||
emptyStringWarningLogged = true;
|
||||
LOGGER.warn("[" + EMPTY_STRING + "] biome string deserialized. This may mean the level was null when a save was attempted, a file saving error, or a biome saving error. Future errors will not be logged.");
|
||||
}
|
||||
return EMPTY_WRAPPER;
|
||||
}
|
||||
else if (resourceLocationString.trim().isEmpty() || resourceLocationString.equals(""))
|
||||
@@ -253,10 +275,10 @@ public class BiomeWrapper implements IBiomeWrapper
|
||||
net.minecraft.core.RegistryAccess registryAccess = level.registryAccess();
|
||||
|
||||
boolean success;
|
||||
#if MC_1_16_5 || MC_1_17_1
|
||||
#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_1_18_2 || MC_1_19_2
|
||||
#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);
|
||||
@@ -270,9 +292,9 @@ public class BiomeWrapper implements IBiomeWrapper
|
||||
|
||||
if (!success)
|
||||
{
|
||||
if (!BrokenResourceLocationStrings.contains(resourceLocationString))
|
||||
if (!brokenResourceLocationStrings.contains(resourceLocationString))
|
||||
{
|
||||
BrokenResourceLocationStrings.add(resourceLocationString);
|
||||
brokenResourceLocationStrings.add(resourceLocationString);
|
||||
LOGGER.warn("Unable to deserialize biome from string: [" + resourceLocationString + "]");
|
||||
}
|
||||
return EMPTY_WRAPPER;
|
||||
|
||||
+158
-17
@@ -24,7 +24,10 @@ import com.seibel.distanthorizons.core.wrapperInterfaces.block.IBlockStateWrappe
|
||||
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.tags.BlockTags;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.SoundType;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
@@ -32,15 +35,16 @@ import java.io.IOException;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
#if MC_1_16_5 || MC_1_17_1
|
||||
#if MC_VER == MC_1_16_5 || MC_VER == MC_1_17_1
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.level.EmptyBlockGetter;
|
||||
#elif MC_1_18_2 || MC_1_19_2
|
||||
#elif MC_VER == MC_1_18_2 || MC_VER == MC_1_19_2
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.world.level.EmptyBlockGetter;
|
||||
#else
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.world.level.Level;
|
||||
@@ -79,6 +83,13 @@ public class BlockStateWrapper implements IBlockStateWrapper
|
||||
public final BlockState blockState;
|
||||
/** technically final, but since it requires a method call to generate it can't be marked as such */
|
||||
private String serialString;
|
||||
/**
|
||||
* Cached opacity value, -1 if not populated. <br>
|
||||
* Should be between {@link IBlockStateWrapper#FULLY_OPAQUE} and {@link IBlockStateWrapper#FULLY_OPAQUE}
|
||||
*/
|
||||
private int opacity = -1;
|
||||
/** used by the Iris shader mod to determine how each LOD should be rendered */
|
||||
private byte irisBlockMaterialId = 0;
|
||||
|
||||
|
||||
|
||||
@@ -110,7 +121,8 @@ public class BlockStateWrapper implements IBlockStateWrapper
|
||||
{
|
||||
this.blockState = blockState;
|
||||
this.serialString = this.serialize(levelWrapper);
|
||||
LOGGER.trace("Created BlockStateWrapper ["+this.serialString+"] for ["+blockState+"]");
|
||||
this.irisBlockMaterialId = this.calculateIrisBlockMaterialId();
|
||||
LOGGER.trace("Created BlockStateWrapper ["+this.serialString+"] for ["+blockState+"] with material ID ["+this.irisBlockMaterialId+"]");
|
||||
}
|
||||
|
||||
|
||||
@@ -173,17 +185,39 @@ public class BlockStateWrapper implements IBlockStateWrapper
|
||||
@Override
|
||||
public int getOpacity()
|
||||
{
|
||||
// this method isn't perfect, but works well enough for our use case
|
||||
if (this.isAir() || !this.blockState.canOcclude())
|
||||
// use the cached opacity value if possible
|
||||
if (this.opacity != -1)
|
||||
{
|
||||
// completely transparent
|
||||
return 0;
|
||||
return this.opacity;
|
||||
}
|
||||
|
||||
|
||||
// this method isn't perfect, but works well enough for our use case
|
||||
int opacity;
|
||||
if (this.isAir())
|
||||
{
|
||||
opacity = FULLY_TRANSPARENT;
|
||||
}
|
||||
else if (this.isLiquid() && !this.blockState.canOcclude())
|
||||
{
|
||||
// probably not a waterlogged block (which should block light entirely)
|
||||
|
||||
// +1 to indicate that the block is translucent (in between transparent and opaque)
|
||||
opacity = FULLY_TRANSPARENT + 1;
|
||||
}
|
||||
else if (this.blockState.propagatesSkylightDown(EmptyBlockGetter.INSTANCE, BlockPos.ZERO))
|
||||
{
|
||||
opacity = FULLY_TRANSPARENT;
|
||||
}
|
||||
else
|
||||
{
|
||||
// completely opaque
|
||||
return 16;
|
||||
// default for all other blocks
|
||||
opacity = FULLY_OPAQUE;
|
||||
}
|
||||
|
||||
|
||||
this.opacity = opacity;
|
||||
return this.opacity;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -224,7 +258,7 @@ public class BlockStateWrapper implements IBlockStateWrapper
|
||||
@Override
|
||||
public boolean isSolid()
|
||||
{
|
||||
#if PRE_MC_1_20_1
|
||||
#if MC_VER < MC_1_20_1
|
||||
return this.blockState.getMaterial().isSolid();
|
||||
#else
|
||||
return !this.blockState.getCollisionShape(EmptyBlockGetter.INSTANCE, BlockPos.ZERO).isEmpty();
|
||||
@@ -239,13 +273,16 @@ public class BlockStateWrapper implements IBlockStateWrapper
|
||||
return false;
|
||||
}
|
||||
|
||||
#if PRE_MC_1_20_1
|
||||
#if MC_VER < MC_1_20_1
|
||||
return this.blockState.getMaterial().isLiquid() || !this.blockState.getFluidState().isEmpty();
|
||||
#else
|
||||
return !this.blockState.getFluidState().isEmpty();
|
||||
#endif
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte getIrisBlockMaterialId() { return this.irisBlockMaterialId; }
|
||||
|
||||
@Override
|
||||
public String toString() { return this.getSerialString(); }
|
||||
|
||||
@@ -265,15 +302,15 @@ public class BlockStateWrapper implements IBlockStateWrapper
|
||||
|
||||
|
||||
// older versions of MC have a static registry
|
||||
#if !(MC_1_16_5 || MC_1_17_1)
|
||||
#if MC_VER > MC_1_17_1
|
||||
Level level = (Level)levelWrapper.getWrappedMcObject();
|
||||
net.minecraft.core.RegistryAccess registryAccess = level.registryAccess();
|
||||
#endif
|
||||
|
||||
ResourceLocation resourceLocation;
|
||||
#if MC_1_16_5 || MC_1_17_1
|
||||
#if MC_VER == MC_1_16_5 || MC_VER == MC_1_17_1
|
||||
resourceLocation = Registry.BLOCK.getKey(this.blockState.getBlock());
|
||||
#elif MC_1_18_2 || MC_1_19_2
|
||||
#elif MC_VER == MC_1_18_2 || MC_VER == MC_1_19_2
|
||||
resourceLocation = registryAccess.registryOrThrow(Registry.BLOCK_REGISTRY).getKey(this.blockState.getBlock());
|
||||
#else
|
||||
resourceLocation = registryAccess.registryOrThrow(Registries.BLOCK).getKey(this.blockState.getBlock());
|
||||
@@ -328,16 +365,16 @@ public class BlockStateWrapper implements IBlockStateWrapper
|
||||
try
|
||||
{
|
||||
|
||||
#if !(MC_1_16_5 || MC_1_17_1)
|
||||
#if MC_VER > MC_1_17_1
|
||||
// use the given level if possible, otherwise try using the currently loaded one
|
||||
Level level = (levelWrapper != null ? (Level)levelWrapper.getWrappedMcObject() : null);
|
||||
level = (level == null ? Minecraft.getInstance().level : level);
|
||||
#endif
|
||||
|
||||
Block block;
|
||||
#if MC_1_16_5 || MC_1_17_1
|
||||
#if MC_VER == MC_1_16_5 || MC_VER == MC_1_17_1
|
||||
block = Registry.BLOCK.get(resourceLocation);
|
||||
#elif MC_1_18_2 || MC_1_19_2
|
||||
#elif MC_VER == MC_1_18_2 || MC_VER == MC_1_19_2
|
||||
net.minecraft.core.RegistryAccess registryAccess = level.registryAccess();
|
||||
block = registryAccess.registryOrThrow(Registry.BLOCK_REGISTRY).get(resourceLocation);
|
||||
#else
|
||||
@@ -429,4 +466,108 @@ public class BlockStateWrapper implements IBlockStateWrapper
|
||||
|
||||
|
||||
|
||||
//==============//
|
||||
// Iris methods //
|
||||
//==============//
|
||||
|
||||
private byte calculateIrisBlockMaterialId()
|
||||
{
|
||||
if (this.blockState == null)
|
||||
{
|
||||
return IrisBlockMaterial.AIR;
|
||||
}
|
||||
|
||||
|
||||
String serialString = this.getSerialString().toLowerCase();
|
||||
|
||||
if (this.blockState.is(BlockTags.LEAVES)
|
||||
|| serialString.contains("bamboo")
|
||||
|| serialString.contains("cactus")
|
||||
|| serialString.contains("chorus_flower")
|
||||
|| serialString.contains("mushroom")
|
||||
)
|
||||
{
|
||||
return IrisBlockMaterial.LEAVES;
|
||||
}
|
||||
else if (this.blockState.is(Blocks.LAVA))
|
||||
{
|
||||
return IrisBlockMaterial.LAVA;
|
||||
}
|
||||
else if (this.isLiquid() || this.blockState.is(Blocks.WATER))
|
||||
{
|
||||
return IrisBlockMaterial.WATER;
|
||||
}
|
||||
else if (this.blockState.getSoundType() == SoundType.WOOD
|
||||
|| serialString.contains("root")
|
||||
#if MC_VER >= MC_1_19_4
|
||||
|| this.blockState.getSoundType() == SoundType.CHERRY_WOOD
|
||||
#endif
|
||||
)
|
||||
{
|
||||
return IrisBlockMaterial.WOOD;
|
||||
}
|
||||
else if (this.blockState.getSoundType() == SoundType.METAL
|
||||
#if MC_VER >= MC_1_19_2
|
||||
|| this.blockState.getSoundType() == SoundType.COPPER
|
||||
#endif
|
||||
#if MC_VER >= MC_1_20_4
|
||||
|| this.blockState.getSoundType() == SoundType.COPPER_BULB
|
||||
|| this.blockState.getSoundType() == SoundType.COPPER_GRATE
|
||||
#endif
|
||||
)
|
||||
{
|
||||
return IrisBlockMaterial.METAL;
|
||||
}
|
||||
else if (
|
||||
serialString.contains("dirt")
|
||||
|| serialString.contains("grass_block")
|
||||
|| serialString.contains("gravel")
|
||||
|| serialString.contains("mud")
|
||||
|| serialString.contains("podzol")
|
||||
|| serialString.contains("mycelium")
|
||||
)
|
||||
{
|
||||
return IrisBlockMaterial.DIRT;
|
||||
}
|
||||
#if MC_VER >= MC_1_17_1
|
||||
else if (this.blockState.getSoundType() == SoundType.DEEPSLATE
|
||||
|| this.blockState.getSoundType() == SoundType.DEEPSLATE_BRICKS
|
||||
|| this.blockState.getSoundType() == SoundType.DEEPSLATE_TILES
|
||||
|| this.blockState.getSoundType() == SoundType.POLISHED_DEEPSLATE
|
||||
|| serialString.contains("deepslate") )
|
||||
{
|
||||
return IrisBlockMaterial.DEEPSLATE;
|
||||
}
|
||||
#endif
|
||||
else if (this.serialString.contains("snow"))
|
||||
{
|
||||
return IrisBlockMaterial.SNOW;
|
||||
}
|
||||
else if (serialString.contains("sand"))
|
||||
{
|
||||
return IrisBlockMaterial.SAND;
|
||||
}
|
||||
else if (serialString.contains("terracotta"))
|
||||
{
|
||||
return IrisBlockMaterial.TERRACOTTA;
|
||||
}
|
||||
else if (this.blockState.is(BlockTags.BASE_STONE_NETHER))
|
||||
{
|
||||
return IrisBlockMaterial.NETHER_STONE;
|
||||
}
|
||||
else if (serialString.contains("stone")
|
||||
|| serialString.contains("ore"))
|
||||
{
|
||||
return IrisBlockMaterial.STONE;
|
||||
}
|
||||
else if (this.blockState.getLightEmission() > 0)
|
||||
{
|
||||
return IrisBlockMaterial.ILLUMINATED;
|
||||
}
|
||||
else
|
||||
{
|
||||
return IrisBlockMaterial.UNKOWN;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+2
-2
@@ -40,11 +40,11 @@ public class TextureAtlasSpriteWrapper
|
||||
*/
|
||||
public static int getPixelRGBA(TextureAtlasSprite sprite, int frameIndex, int x, int y)
|
||||
{
|
||||
#if PRE_MC_1_17_1
|
||||
#if MC_VER < MC_1_17_1
|
||||
return sprite.mainImage[0].getPixelRGBA(
|
||||
x + sprite.framesX[frameIndex] * sprite.getWidth(),
|
||||
y + sprite.framesY[frameIndex] * sprite.getHeight());
|
||||
#elif PRE_MC_1_19_4
|
||||
#elif MC_VER < MC_1_19_4
|
||||
if (sprite.animatedTexture != null)
|
||||
{
|
||||
x += sprite.animatedTexture.getFrameX(frameIndex) * sprite.width;
|
||||
|
||||
+3
-15
@@ -19,7 +19,6 @@
|
||||
|
||||
package com.seibel.distanthorizons.common.wrappers.block;
|
||||
|
||||
import com.seibel.distanthorizons.common.LodCommonMain;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.world.level.*;
|
||||
@@ -50,7 +49,7 @@ public class TintGetterOverrideFast implements BlockAndTintGetter
|
||||
|
||||
private Biome _getBiome(BlockPos pos)
|
||||
{
|
||||
#if POST_MC_1_18_2
|
||||
#if MC_VER >= MC_1_18_2
|
||||
return parent.getBiome(pos).value();
|
||||
#else
|
||||
return parent.getBiome(pos);
|
||||
@@ -58,18 +57,7 @@ public class TintGetterOverrideFast implements BlockAndTintGetter
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBlockTint(BlockPos blockPos, ColorResolver colorResolver)
|
||||
{
|
||||
if (LodCommonMain.forgeMethodCaller != null)
|
||||
{
|
||||
return LodCommonMain.forgeMethodCaller.colorResolverGetColor(colorResolver, _getBiome(blockPos),
|
||||
blockPos.getX(), blockPos.getZ());
|
||||
}
|
||||
else
|
||||
{
|
||||
return colorResolver.getColor(_getBiome(blockPos), blockPos.getX(), blockPos.getZ());
|
||||
}
|
||||
}
|
||||
public int getBlockTint(BlockPos blockPos, ColorResolver colorResolver) { return colorResolver.getColor(this._getBiome(blockPos), blockPos.getX(), blockPos.getZ()); }
|
||||
|
||||
@Override
|
||||
public float getShade(Direction direction, boolean bl) { return this.parent.getShade(direction, bl); }
|
||||
@@ -167,7 +155,7 @@ public class TintGetterOverrideFast implements BlockAndTintGetter
|
||||
return parent.getMaxBuildHeight();
|
||||
}
|
||||
|
||||
#if POST_MC_1_17_1
|
||||
#if MC_VER >= MC_1_17_1
|
||||
@Override
|
||||
public <T extends BlockEntity> Optional<T> getBlockEntity(BlockPos blockPos, BlockEntityType<T> blockEntityType)
|
||||
{
|
||||
|
||||
+31
-122
@@ -19,7 +19,6 @@
|
||||
|
||||
package com.seibel.distanthorizons.common.wrappers.block;
|
||||
|
||||
import com.seibel.distanthorizons.common.LodCommonMain;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Cursor3D;
|
||||
import net.minecraft.core.Direction;
|
||||
@@ -53,7 +52,7 @@ public class TintGetterOverrideSmooth implements BlockAndTintGetter
|
||||
|
||||
private Biome _getBiome(BlockPos pos)
|
||||
{
|
||||
#if POST_MC_1_18_2
|
||||
#if MC_VER >= MC_1_18_2
|
||||
return parent.getBiome(pos).value();
|
||||
#else
|
||||
return parent.getBiome(pos);
|
||||
@@ -74,16 +73,7 @@ public class TintGetterOverrideSmooth implements BlockAndTintGetter
|
||||
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());
|
||||
}
|
||||
int n = colorResolver.getColor(this._getBiome(mutableBlockPos), mutableBlockPos.getX(), mutableBlockPos.getZ());
|
||||
|
||||
k += (n & 0xFF0000) >> 16;
|
||||
l += (n & 0xFF00) >> 8;
|
||||
@@ -93,177 +83,96 @@ public class TintGetterOverrideSmooth implements BlockAndTintGetter
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBlockTint(BlockPos blockPos, ColorResolver colorResolver)
|
||||
{
|
||||
return calculateBlockTint(blockPos, colorResolver);
|
||||
}
|
||||
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 parent.getLightEngine();
|
||||
}
|
||||
public LevelLightEngine getLightEngine() { return this.parent.getLightEngine(); }
|
||||
|
||||
@Override
|
||||
public int getBrightness(LightLayer lightLayer, BlockPos blockPos)
|
||||
{
|
||||
return parent.getBrightness(lightLayer, blockPos);
|
||||
}
|
||||
public int getBrightness(LightLayer lightLayer, BlockPos blockPos) { return this.parent.getBrightness(lightLayer, blockPos); }
|
||||
|
||||
@Override
|
||||
public int getRawBrightness(BlockPos blockPos, int i)
|
||||
{
|
||||
return parent.getRawBrightness(blockPos, i);
|
||||
}
|
||||
public int getRawBrightness(BlockPos blockPos, int i) { return this.parent.getRawBrightness(blockPos, i); }
|
||||
|
||||
@Override
|
||||
public boolean canSeeSky(BlockPos blockPos)
|
||||
{
|
||||
return parent.canSeeSky(blockPos);
|
||||
}
|
||||
public boolean canSeeSky(BlockPos blockPos) { return this.parent.canSeeSky(blockPos); }
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public BlockEntity getBlockEntity(BlockPos blockPos)
|
||||
{
|
||||
return parent.getBlockEntity(blockPos);
|
||||
}
|
||||
public BlockEntity getBlockEntity(BlockPos blockPos) { return this.parent.getBlockEntity(blockPos); }
|
||||
|
||||
@Override
|
||||
public BlockState getBlockState(BlockPos blockPos)
|
||||
{
|
||||
return parent.getBlockState(blockPos);
|
||||
}
|
||||
public BlockState getBlockState(BlockPos blockPos) { return this.parent.getBlockState(blockPos); }
|
||||
|
||||
@Override
|
||||
public FluidState getFluidState(BlockPos blockPos)
|
||||
{
|
||||
return parent.getFluidState(blockPos);
|
||||
}
|
||||
public FluidState getFluidState(BlockPos blockPos) { return this.parent.getFluidState(blockPos); }
|
||||
|
||||
@Override
|
||||
public int getLightEmission(BlockPos blockPos)
|
||||
{
|
||||
return parent.getLightEmission(blockPos);
|
||||
}
|
||||
public int getLightEmission(BlockPos blockPos) { return this.parent.getLightEmission(blockPos); }
|
||||
|
||||
@Override
|
||||
public int getMaxLightLevel()
|
||||
{
|
||||
return parent.getMaxLightLevel();
|
||||
}
|
||||
public int getMaxLightLevel() { return this.parent.getMaxLightLevel(); }
|
||||
|
||||
@Override
|
||||
public Stream<BlockState> getBlockStates(AABB aABB)
|
||||
{
|
||||
return parent.getBlockStates(aABB);
|
||||
}
|
||||
public Stream<BlockState> getBlockStates(AABB aABB) { return this.parent.getBlockStates(aABB); }
|
||||
|
||||
@Override
|
||||
public BlockHitResult clip(ClipContext clipContext)
|
||||
{
|
||||
return parent.clip(clipContext);
|
||||
}
|
||||
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 parent.clipWithInteractionOverride(vec3, vec32, blockPos, voxelShape, blockState);
|
||||
return this.parent.clipWithInteractionOverride(vec3, vec32, blockPos, voxelShape, blockState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getBlockFloorHeight(VoxelShape voxelShape, Supplier<VoxelShape> supplier)
|
||||
{
|
||||
return parent.getBlockFloorHeight(voxelShape, supplier);
|
||||
}
|
||||
public double getBlockFloorHeight(VoxelShape voxelShape, Supplier<VoxelShape> supplier) { return this.parent.getBlockFloorHeight(voxelShape, supplier); }
|
||||
|
||||
@Override
|
||||
public double getBlockFloorHeight(BlockPos blockPos)
|
||||
{
|
||||
return parent.getBlockFloorHeight(blockPos);
|
||||
}
|
||||
public double getBlockFloorHeight(BlockPos blockPos) { return this.parent.getBlockFloorHeight(blockPos); }
|
||||
|
||||
@Override
|
||||
public int getMaxBuildHeight()
|
||||
{
|
||||
return parent.getMaxBuildHeight();
|
||||
}
|
||||
public int getMaxBuildHeight() { return this.parent.getMaxBuildHeight(); }
|
||||
|
||||
#if POST_MC_1_17_1
|
||||
#if MC_VER >= MC_1_17_1
|
||||
@Override
|
||||
public <T extends BlockEntity> Optional<T> getBlockEntity(BlockPos blockPos, BlockEntityType<T> blockEntityType)
|
||||
{
|
||||
return parent.getBlockEntity(blockPos, blockEntityType);
|
||||
}
|
||||
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 parent.isBlockInLine(clipBlockStateContext);
|
||||
}
|
||||
public BlockHitResult isBlockInLine(ClipBlockStateContext clipBlockStateContext) { return this.parent.isBlockInLine(clipBlockStateContext); }
|
||||
|
||||
@Override
|
||||
public int getHeight()
|
||||
{
|
||||
return parent.getHeight();
|
||||
}
|
||||
public int getHeight() { return this.parent.getHeight(); }
|
||||
|
||||
@Override
|
||||
public int getMinBuildHeight()
|
||||
{
|
||||
return parent.getMinBuildHeight();
|
||||
}
|
||||
public int getMinBuildHeight() { return this.parent.getMinBuildHeight(); }
|
||||
|
||||
@Override
|
||||
public int getSectionsCount()
|
||||
{
|
||||
return parent.getSectionsCount();
|
||||
}
|
||||
public int getSectionsCount() { return this.parent.getSectionsCount(); }
|
||||
|
||||
@Override
|
||||
public int getMinSection()
|
||||
{
|
||||
return parent.getMinSection();
|
||||
}
|
||||
public int getMinSection() { return this.parent.getMinSection(); }
|
||||
|
||||
@Override
|
||||
public int getMaxSection()
|
||||
{
|
||||
return parent.getMaxSection();
|
||||
}
|
||||
public int getMaxSection() { return this.parent.getMaxSection(); }
|
||||
|
||||
@Override
|
||||
public boolean isOutsideBuildHeight(BlockPos blockPos)
|
||||
{
|
||||
return parent.isOutsideBuildHeight(blockPos);
|
||||
}
|
||||
public boolean isOutsideBuildHeight(BlockPos blockPos) { return this.parent.isOutsideBuildHeight(blockPos); }
|
||||
|
||||
@Override
|
||||
public boolean isOutsideBuildHeight(int i)
|
||||
{
|
||||
return parent.isOutsideBuildHeight(i);
|
||||
}
|
||||
public boolean isOutsideBuildHeight(int i) { return this.parent.isOutsideBuildHeight(i); }
|
||||
|
||||
@Override
|
||||
public int getSectionIndex(int i)
|
||||
{
|
||||
return parent.getSectionIndex(i);
|
||||
}
|
||||
public int getSectionIndex(int i) { return this.parent.getSectionIndex(i); }
|
||||
|
||||
@Override
|
||||
public int getSectionIndexFromSectionY(int i)
|
||||
{
|
||||
return parent.getSectionIndexFromSectionY(i);
|
||||
}
|
||||
public int getSectionIndexFromSectionY(int i) { return this.parent.getSectionIndexFromSectionY(i); }
|
||||
|
||||
@Override
|
||||
public int getSectionYFromSectionIndex(int i)
|
||||
{
|
||||
return parent.getSectionYFromSectionIndex(i);
|
||||
}
|
||||
public int getSectionYFromSectionIndex(int i) { return this.parent.getSectionYFromSectionIndex(i); }
|
||||
#endif
|
||||
}
|
||||
|
||||
+4
-4
@@ -29,7 +29,7 @@ import net.minecraft.world.level.lighting.LevelLightEngine;
|
||||
import net.minecraft.world.level.material.FluidState;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
#if POST_MC_1_18_2
|
||||
#if MC_VER >= MC_1_18_2
|
||||
import net.minecraft.core.Holder;
|
||||
#endif
|
||||
|
||||
@@ -46,9 +46,9 @@ public class TintWithoutLevelOverrider implements BlockAndTintGetter
|
||||
{
|
||||
return colorResolver.getColor(_unwrap(biome.biome), blockPos.getX(), blockPos.getZ());
|
||||
}
|
||||
private Biome _unwrap(#if POST_MC_1_18_2 Holder<Biome> #else Biome #endif biome)
|
||||
private Biome _unwrap(#if MC_VER >= MC_1_18_2 Holder<Biome> #else Biome #endif biome)
|
||||
{
|
||||
#if POST_MC_1_18_2
|
||||
#if MC_VER >= MC_1_18_2
|
||||
return biome.value();
|
||||
#else
|
||||
return biome;
|
||||
@@ -84,7 +84,7 @@ public class TintWithoutLevelOverrider implements BlockAndTintGetter
|
||||
}
|
||||
|
||||
|
||||
#if MC_1_17_1 || POST_MC_1_18_2
|
||||
#if MC_VER >= MC_1_17_1
|
||||
@Override
|
||||
public int getHeight()
|
||||
{
|
||||
|
||||
+4
-4
@@ -30,7 +30,7 @@ import net.minecraft.world.level.lighting.LevelLightEngine;
|
||||
import net.minecraft.world.level.material.FluidState;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
#if POST_MC_1_18_2
|
||||
#if MC_VER >= MC_1_18_2
|
||||
import net.minecraft.core.Holder;
|
||||
#endif
|
||||
|
||||
@@ -49,9 +49,9 @@ public class TintWithoutLevelSmoothOverrider implements BlockAndTintGetter
|
||||
{
|
||||
return colorResolver.getColor(_unwrap(biome.biome), blockPos.getX(), blockPos.getZ());
|
||||
}
|
||||
private Biome _unwrap(#if POST_MC_1_18_2 Holder<Biome> #else Biome #endif biome)
|
||||
private Biome _unwrap(#if MC_VER >= MC_1_18_2 Holder<Biome> #else Biome #endif biome)
|
||||
{
|
||||
#if POST_MC_1_18_2
|
||||
#if MC_VER >= MC_1_18_2
|
||||
return biome.value();
|
||||
#else
|
||||
return biome;
|
||||
@@ -116,7 +116,7 @@ public class TintWithoutLevelSmoothOverrider implements BlockAndTintGetter
|
||||
}
|
||||
|
||||
|
||||
#if MC_1_17_1 || POST_MC_1_18_2
|
||||
#if MC_VER >= MC_1_17_1
|
||||
@Override
|
||||
public int getHeight()
|
||||
{
|
||||
|
||||
+1
-1
@@ -29,7 +29,7 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
public class ClientBlockDetailMap
|
||||
{
|
||||
private final ConcurrentHashMap<BlockState, ClientBlockStateCache> blockCache = new ConcurrentHashMap<>();
|
||||
//private final ConcurrentHashMap<#if PRE_MC_1_18_2 Biome #else Holder<Biome> #endif, Biome> biomeMap = new ConcurrentHashMap<>();
|
||||
//private final ConcurrentHashMap<#if MC_VER < MC_1_18_2 Biome #else Holder<Biome> #endif, Biome> biomeMap = new ConcurrentHashMap<>();
|
||||
private final ClientLevelWrapper level;
|
||||
public ClientBlockDetailMap(ClientLevelWrapper level) { this.level = level; }
|
||||
|
||||
|
||||
+16
-7
@@ -38,7 +38,7 @@ import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.FlowerBlock;
|
||||
import net.minecraft.world.level.block.LeavesBlock;
|
||||
import net.minecraft.world.level.block.RotatedPillarBlock;
|
||||
#if POST_MC_1_19_2
|
||||
#if MC_VER >= MC_1_19_2
|
||||
import net.minecraft.util.RandomSource;
|
||||
#else
|
||||
import java.util.Random;
|
||||
@@ -60,7 +60,7 @@ public class ClientBlockStateCache
|
||||
private static final HashSet<BlockState> BLOCK_STATES_THAT_NEED_LEVEL = new HashSet<>();
|
||||
private static final HashSet<BlockState> BROKEN_BLOCK_STATES = new HashSet<>();
|
||||
|
||||
#if PRE_MC_1_19_2
|
||||
#if MC_VER < MC_1_19_2
|
||||
public static final Random random = new Random(0);
|
||||
#else
|
||||
public static final RandomSource random = RandomSource.create();
|
||||
@@ -91,18 +91,20 @@ public class ClientBlockStateCache
|
||||
{
|
||||
Default,
|
||||
Flower,
|
||||
Leaves;
|
||||
Leaves,
|
||||
Chisel;
|
||||
static ColorMode getColorMode(Block b)
|
||||
{
|
||||
if (b instanceof LeavesBlock) return Leaves;
|
||||
if (b instanceof FlowerBlock) return Flower;
|
||||
if (b.toString().equals("Block{chiselsandbits:chiseled}")) return Chisel;
|
||||
return Default;
|
||||
}
|
||||
}
|
||||
|
||||
private static int getWidth(TextureAtlasSprite texture)
|
||||
{
|
||||
#if PRE_MC_1_19_4
|
||||
#if MC_VER < MC_1_19_4
|
||||
return texture.getWidth();
|
||||
#else
|
||||
return texture.contents().width();
|
||||
@@ -111,7 +113,7 @@ public class ClientBlockStateCache
|
||||
|
||||
private static int getHeight(TextureAtlasSprite texture)
|
||||
{
|
||||
#if PRE_MC_1_19_4
|
||||
#if MC_VER < MC_1_19_4
|
||||
return texture.getHeight();
|
||||
#else
|
||||
return texture.contents().height();
|
||||
@@ -160,7 +162,14 @@ public class ClientBlockStateCache
|
||||
{
|
||||
scale = FLOWER_COLOR_SCALE;
|
||||
}
|
||||
|
||||
//make Chiseled block not render
|
||||
else if (colorMode == ColorMode.Chisel)
|
||||
{
|
||||
r = 0;
|
||||
g = 0;
|
||||
b = 0;
|
||||
a = 0;
|
||||
}
|
||||
count += scale;
|
||||
alpha += a * a * scale;
|
||||
red += r * r * scale;
|
||||
@@ -211,7 +220,7 @@ public class ClientBlockStateCache
|
||||
needShade = quads.get(0).isShade();
|
||||
tintIndex = quads.get(0).getTintIndex();
|
||||
baseColor = calculateColorFromTexture(
|
||||
#if PRE_MC_1_17_1 quads.get(0).sprite,
|
||||
#if MC_VER < MC_1_17_1 quads.get(0).sprite,
|
||||
#else quads.get(0).getSprite(), #endif
|
||||
ColorMode.getColorMode(blockState.getBlock()));
|
||||
}
|
||||
|
||||
+1
-1
@@ -29,7 +29,7 @@ import net.minecraft.world.level.block.state.BlockState;
|
||||
public class ServerBlockDetailMap
|
||||
{
|
||||
private final ConcurrentHashMap<BlockState, ServerBlockStateCache> blockCache = new ConcurrentHashMap<>();
|
||||
//private final ConcurrentHashMap<#if PRE_MC_1_18_2 Biome #else Holder<Biome> #endif, Biome> biomeMap = new ConcurrentHashMap<>();
|
||||
//private final ConcurrentHashMap<#if MC_VER < MC_1_18_2 Biome #else Holder<Biome> #endif, Biome> biomeMap = new ConcurrentHashMap<>();
|
||||
private final ServerLevelWrapper level;
|
||||
public ServerBlockDetailMap(ServerLevelWrapper level) { this.level = level; }
|
||||
|
||||
|
||||
+98
-40
@@ -31,6 +31,7 @@ import com.seibel.distanthorizons.core.wrapperInterfaces.chunk.IChunkWrapper;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IBiomeWrapper;
|
||||
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper;
|
||||
import com.seibel.distanthorizons.coreapi.ModInfo;
|
||||
import net.minecraft.client.multiplayer.ClientChunkCache;
|
||||
import net.minecraft.client.multiplayer.ClientLevel;
|
||||
import net.minecraft.core.BlockPos;
|
||||
@@ -46,27 +47,27 @@ import org.apache.logging.log4j.Logger;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
|
||||
#if POST_MC_1_17_1
|
||||
#if MC_VER >= MC_1_17_1
|
||||
import net.minecraft.core.QuartPos;
|
||||
#endif
|
||||
|
||||
#if MC_1_16_5
|
||||
#if MC_VER == MC_1_16_5
|
||||
import net.minecraft.world.level.chunk.LevelChunkSection;
|
||||
#endif
|
||||
|
||||
#if MC_1_17_1
|
||||
#if MC_VER == MC_1_17_1
|
||||
import net.minecraft.world.level.chunk.LevelChunkSection;
|
||||
#endif
|
||||
|
||||
#if MC_1_18_2
|
||||
#if MC_VER == MC_1_18_2
|
||||
import net.minecraft.world.level.chunk.LevelChunkSection;
|
||||
#endif
|
||||
|
||||
#if MC_1_19_2 || MC_1_19_4
|
||||
#if MC_VER == MC_1_19_2 || MC_VER == MC_1_19_4
|
||||
import net.minecraft.world.level.chunk.LevelChunkSection;
|
||||
#endif
|
||||
|
||||
#if POST_MC_1_20_1
|
||||
#if MC_VER >= MC_1_20_1
|
||||
import net.minecraft.world.level.chunk.LevelChunkSection;
|
||||
import net.minecraft.world.level.lighting.LevelLightEngine;
|
||||
import net.minecraft.core.SectionPos;
|
||||
@@ -77,7 +78,7 @@ public class ChunkWrapper implements IChunkWrapper
|
||||
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
|
||||
|
||||
/** useful for debugging, but can slow down chunk operations quite a bit due to being called every time. */
|
||||
private static final boolean RUN_RELATIVE_POS_INDEX_VALIDATION = false;
|
||||
private static final boolean RUN_RELATIVE_POS_INDEX_VALIDATION = ModInfo.IS_DEV_BUILD;
|
||||
|
||||
/** 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());
|
||||
@@ -99,6 +100,9 @@ public class ChunkWrapper implements IChunkWrapper
|
||||
|
||||
private boolean useDhLighting;
|
||||
|
||||
private int minNonEmptyHeight = Integer.MIN_VALUE;
|
||||
private int maxNonEmptyHeight = Integer.MAX_VALUE;
|
||||
|
||||
/**
|
||||
* Due to vanilla `isClientLightReady()` not being designed for use by a non-render thread, it may return 'true'
|
||||
* before the light engine has ticked, (right after all light changes is marked by the engine to be processed).
|
||||
@@ -144,7 +148,7 @@ public class ChunkWrapper implements IChunkWrapper
|
||||
@Override
|
||||
public int getHeight()
|
||||
{
|
||||
#if PRE_MC_1_17_1
|
||||
#if MC_VER < MC_1_17_1
|
||||
return 255;
|
||||
#else
|
||||
return this.chunk.getHeight();
|
||||
@@ -154,7 +158,7 @@ public class ChunkWrapper implements IChunkWrapper
|
||||
@Override
|
||||
public int getMinBuildHeight()
|
||||
{
|
||||
#if PRE_MC_1_17_1
|
||||
#if MC_VER < MC_1_17_1
|
||||
return 0;
|
||||
#else
|
||||
return this.chunk.getMinBuildHeight();
|
||||
@@ -164,8 +168,18 @@ public class ChunkWrapper implements IChunkWrapper
|
||||
public int getMaxBuildHeight() { return this.chunk.getMaxBuildHeight(); }
|
||||
|
||||
@Override
|
||||
public int getMinFilledHeight()
|
||||
public int getMinNonEmptyHeight()
|
||||
{
|
||||
if (this.minNonEmptyHeight != Integer.MIN_VALUE)
|
||||
{
|
||||
return this.minNonEmptyHeight;
|
||||
}
|
||||
|
||||
|
||||
// default if every section is empty or missing
|
||||
this.minNonEmptyHeight = this.getMinBuildHeight();
|
||||
|
||||
// determine the lowest empty section (bottom up)
|
||||
LevelChunkSection[] sections = this.chunk.getSections();
|
||||
for (int index = 0; index < sections.length; index++)
|
||||
{
|
||||
@@ -174,27 +188,65 @@ public class ChunkWrapper implements IChunkWrapper
|
||||
continue;
|
||||
}
|
||||
|
||||
#if MC_1_16_5
|
||||
if (!sections[index].isEmpty())
|
||||
if (!isChunkSectionEmpty(sections[index]))
|
||||
{
|
||||
// convert from an index to a block coordinate
|
||||
return this.chunk.getSections()[index].bottomBlockY() * 16;
|
||||
this.minNonEmptyHeight = this.getChunkSectionMinHeight(index);
|
||||
break;
|
||||
}
|
||||
#elif MC_1_17_1
|
||||
if (!sections[index].isEmpty())
|
||||
{
|
||||
// convert from an index to a block coordinate
|
||||
return this.chunk.getSections()[index].bottomBlockY() * 16;
|
||||
}
|
||||
#else
|
||||
if (!sections[index].hasOnlyAir())
|
||||
{
|
||||
// convert from an index to a block coordinate
|
||||
return this.chunk.getSectionYFromSectionIndex(index) * 16;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return Integer.MAX_VALUE;
|
||||
|
||||
return this.minNonEmptyHeight;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getMaxNonEmptyHeight()
|
||||
{
|
||||
if (this.maxNonEmptyHeight != Integer.MAX_VALUE)
|
||||
{
|
||||
return this.maxNonEmptyHeight;
|
||||
}
|
||||
|
||||
|
||||
// default if every section is empty or missing
|
||||
this.maxNonEmptyHeight = this.getMaxBuildHeight();
|
||||
|
||||
// determine the highest empty section (top down)
|
||||
LevelChunkSection[] sections = this.chunk.getSections();
|
||||
for (int index = sections.length-1; index >= 0; index--)
|
||||
{
|
||||
if (sections[index] == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!isChunkSectionEmpty(sections[index]))
|
||||
{
|
||||
this.maxNonEmptyHeight = this.getChunkSectionMinHeight(index) + 16;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return this.maxNonEmptyHeight;
|
||||
}
|
||||
private static boolean isChunkSectionEmpty(LevelChunkSection section)
|
||||
{
|
||||
#if MC_VER == MC_1_16_5
|
||||
return section.isEmpty();
|
||||
#elif MC_VER == MC_1_17_1
|
||||
return section.isEmpty();
|
||||
#else
|
||||
return section.hasOnlyAir();
|
||||
#endif
|
||||
}
|
||||
private int getChunkSectionMinHeight(int index)
|
||||
{
|
||||
// convert from an index to a block coordinate
|
||||
#if MC_VER == MC_1_16_5 || MC_VER == MC_1_17_1
|
||||
return this.chunk.getSections()[index].bottomBlockY();
|
||||
#else
|
||||
return this.chunk.getSectionYFromSectionIndex(index) * 16;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -209,15 +261,15 @@ public class ChunkWrapper implements IChunkWrapper
|
||||
@Override
|
||||
public IBiomeWrapper getBiome(int relX, int relY, int relZ)
|
||||
{
|
||||
#if PRE_MC_1_17_1
|
||||
#if MC_VER < MC_1_17_1
|
||||
return BiomeWrapper.getBiomeWrapper(this.chunk.getBiomes().getNoiseBiome(
|
||||
relX >> 2, relY >> 2, relZ >> 2),
|
||||
this.wrappedLevel);
|
||||
#elif PRE_MC_1_18_2
|
||||
#elif MC_VER < MC_1_18_2
|
||||
return BiomeWrapper.getBiomeWrapper(this.chunk.getBiomes().getNoiseBiome(
|
||||
QuartPos.fromBlock(relX), QuartPos.fromBlock(relY), QuartPos.fromBlock(relZ)),
|
||||
this.wrappedLevel);
|
||||
#elif PRE_MC_1_18_2
|
||||
#elif MC_VER < MC_1_18_2
|
||||
return BiomeWrapper.getBiomeWrapper(this.chunk.getNoiseBiome(
|
||||
QuartPos.fromBlock(relX), QuartPos.fromBlock(relY), QuartPos.fromBlock(relZ)),
|
||||
this.wrappedLevel);
|
||||
@@ -263,7 +315,7 @@ public class ChunkWrapper implements IChunkWrapper
|
||||
}
|
||||
|
||||
|
||||
#if MC_1_16_5 || MC_1_17_1
|
||||
#if MC_VER == MC_1_16_5 || MC_VER == MC_1_17_1
|
||||
return false; // MC's lighting engine doesn't work consistently enough to trust for 1.16 or 1.17
|
||||
#else
|
||||
if (this.chunk instanceof LevelChunk)
|
||||
@@ -373,8 +425,12 @@ public class ChunkWrapper implements IChunkWrapper
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* FIXME synchronized is necessary for a rare issue where this method is called from two separate threads at the same time
|
||||
* before the list has finished populating.
|
||||
*/
|
||||
@Override
|
||||
public ArrayList<DhBlockPos> getBlockLightPosList()
|
||||
public synchronized ArrayList<DhBlockPos> getBlockLightPosList()
|
||||
{
|
||||
// only populate the list once
|
||||
if (this.blockLightPosList == null)
|
||||
@@ -382,12 +438,12 @@ public class ChunkWrapper implements IChunkWrapper
|
||||
this.blockLightPosList = new ArrayList<>();
|
||||
|
||||
|
||||
#if PRE_MC_1_20_1
|
||||
#if MC_VER < MC_1_20_1
|
||||
this.chunk.getLights().forEach((blockPos) ->
|
||||
{
|
||||
this.blockLightPosList.add(new DhBlockPos(blockPos.getX(), blockPos.getY(), blockPos.getZ()));
|
||||
});
|
||||
#elif MC_1_20_1
|
||||
#else
|
||||
this.chunk.findBlockLightSources((blockPos, blockState) ->
|
||||
{
|
||||
this.blockLightPosList.add(new DhBlockPos(blockPos.getX(), blockPos.getY(), blockPos.getZ()));
|
||||
@@ -432,6 +488,8 @@ public class ChunkWrapper implements IChunkWrapper
|
||||
@Override
|
||||
public IBlockStateWrapper getBlockState(int relX, int relY, int relZ)
|
||||
{
|
||||
this.throwIndexOutOfBoundsIfRelativePosOutsideChunkBounds(relX, relY, relZ);
|
||||
|
||||
BlockPos.MutableBlockPos blockPos = MUTABLE_BLOCK_POS_REF.get();
|
||||
|
||||
blockPos.setX(relX);
|
||||
@@ -447,7 +505,7 @@ public class ChunkWrapper implements IChunkWrapper
|
||||
|
||||
public static void syncedUpdateClientLightStatus()
|
||||
{
|
||||
#if PRE_MC_1_18_2
|
||||
#if MC_VER < MC_1_18_2
|
||||
// TODO: Check what to do in 1.18.1 and older
|
||||
|
||||
// since we don't currently handle this list,
|
||||
@@ -474,16 +532,16 @@ public class ChunkWrapper implements IChunkWrapper
|
||||
LevelChunk levelChunk = (LevelChunk) this.chunk;
|
||||
ClientChunkCache clientChunkCache = ((ClientLevel) levelChunk.getLevel()).getChunkSource();
|
||||
this.isMcClientLightingCorrect = clientChunkCache.getChunkForLighting(this.chunk.getPos().x, this.chunk.getPos().z) != null &&
|
||||
#if MC_1_16_5 || MC_1_17_1
|
||||
#if MC_VER <= MC_1_17_1
|
||||
levelChunk.isLightCorrect();
|
||||
#elif PRE_MC_1_20_1
|
||||
#elif MC_VER < MC_1_20_1
|
||||
levelChunk.isClientLightReady();
|
||||
#else
|
||||
checkLightSectionsOnChunk(levelChunk, levelChunk.getLevel().getLightEngine());
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#if POST_MC_1_20_1
|
||||
#if MC_VER >= MC_1_20_1
|
||||
private static boolean checkLightSectionsOnChunk(LevelChunk chunk, LevelLightEngine engine)
|
||||
{
|
||||
LevelChunkSection[] sections = chunk.getSections();
|
||||
@@ -511,7 +569,7 @@ public class ChunkWrapper implements IChunkWrapper
|
||||
/** used to prevent accidentally attempting to get/set values outside this chunk's boundaries */
|
||||
private void throwIndexOutOfBoundsIfRelativePosOutsideChunkBounds(int x, int y, int z) throws IndexOutOfBoundsException
|
||||
{
|
||||
if (RUN_RELATIVE_POS_INDEX_VALIDATION)
|
||||
if (!RUN_RELATIVE_POS_INDEX_VALIDATION)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
+15
-11
@@ -35,7 +35,7 @@ import com.seibel.distanthorizons.coreapi.ModInfo;
|
||||
import net.minecraft.ChatFormatting;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.Font;
|
||||
#if PRE_MC_1_20_1
|
||||
#if MC_VER < MC_1_20_1
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import net.minecraft.client.gui.GuiComponent;
|
||||
#else
|
||||
@@ -49,7 +49,7 @@ import net.minecraft.client.gui.components.events.GuiEventListener;
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.client.resources.language.I18n; // translation
|
||||
#if POST_MC_1_17_1
|
||||
#if MC_VER >= MC_1_17_1
|
||||
import net.minecraft.client.gui.narration.NarratableEntry;
|
||||
#endif
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
@@ -278,7 +278,7 @@ public class ClassicConfigGUI
|
||||
Objects.requireNonNull(minecraft).setScreen(parent);
|
||||
}));
|
||||
|
||||
this.list = new ConfigListWidget(this.minecraft, this.width * 2, this.height, 32, this.height - 32, 25);
|
||||
this.list = new ConfigListWidget(this.minecraft, this.width * 2, this.height, 32, 32, 25);
|
||||
if (this.minecraft != null && this.minecraft.level != null)
|
||||
this.list.setRenderBackground(false);
|
||||
|
||||
@@ -379,13 +379,13 @@ public class ClassicConfigGUI
|
||||
}
|
||||
|
||||
@Override
|
||||
#if PRE_MC_1_20_1
|
||||
#if MC_VER < MC_1_20_1
|
||||
public void render(PoseStack matrices, int mouseX, int mouseY, float delta)
|
||||
#else
|
||||
public void render(GuiGraphics matrices, int mouseX, int mouseY, float delta)
|
||||
#endif
|
||||
{
|
||||
#if PRE_MC_1_20_2 // 1.20.2 now enables this by default in the `this.list.render` function
|
||||
#if MC_VER < MC_1_20_2 // 1.20.2 now enables this by default in the `this.list.render` function
|
||||
this.renderBackground(matrices); // Renders background
|
||||
#else
|
||||
super.render(matrices, mouseX, mouseY, delta);
|
||||
@@ -441,7 +441,7 @@ public class ClassicConfigGUI
|
||||
}
|
||||
}
|
||||
}
|
||||
#if PRE_MC_1_20_2
|
||||
#if MC_VER < MC_1_20_2
|
||||
super.render(matrices, mouseX, mouseY, delta);
|
||||
#endif
|
||||
}
|
||||
@@ -537,9 +537,13 @@ public class ClassicConfigGUI
|
||||
{
|
||||
Font textRenderer;
|
||||
|
||||
public ConfigListWidget(Minecraft minecraftClient, int i, int j, int k, int l, int m)
|
||||
public ConfigListWidget(Minecraft minecraftClient, int canvasWidth, int canvasHeight, int topMargin, int botMargin, int itemSpacing)
|
||||
{
|
||||
super(minecraftClient, i, j, k, l, m);
|
||||
#if MC_VER < MC_1_20_4
|
||||
super(minecraftClient, canvasWidth, canvasHeight, topMargin, canvasHeight - botMargin, itemSpacing);
|
||||
#else
|
||||
super(minecraftClient, canvasWidth, canvasHeight - (topMargin + botMargin), topMargin, itemSpacing);
|
||||
#endif
|
||||
this.centerListVertically = false;
|
||||
textRenderer = minecraftClient.font;
|
||||
}
|
||||
@@ -601,7 +605,7 @@ public class ClassicConfigGUI
|
||||
}
|
||||
|
||||
@Override
|
||||
#if PRE_MC_1_20_1
|
||||
#if MC_VER < MC_1_20_1
|
||||
public void render(PoseStack matrices, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean hovered, float tickDelta)
|
||||
#else
|
||||
public void render(GuiGraphics matrices, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean hovered, float tickDelta)
|
||||
@@ -623,7 +627,7 @@ public class ClassicConfigGUI
|
||||
indexButton.render(matrices, mouseX, mouseY, tickDelta);
|
||||
}
|
||||
if (text != null && (!text.getString().contains("spacer") || button != null))
|
||||
#if PRE_MC_1_20_1
|
||||
#if MC_VER < MC_1_20_1
|
||||
GuiComponent.drawString(matrices, textRenderer, text, 12, y + 5, 0xFFFFFF);
|
||||
#else
|
||||
matrices.drawString(textRenderer, text, 12, y + 5, 0xFFFFFF);
|
||||
@@ -638,7 +642,7 @@ public class ClassicConfigGUI
|
||||
|
||||
// Only for 1.17 and over
|
||||
// Remove in 1.16 and below
|
||||
#if POST_MC_1_17_1
|
||||
#if MC_VER >= MC_1_17_1
|
||||
@Override
|
||||
public List<? extends NarratableEntry> narratables()
|
||||
{
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package com.seibel.distanthorizons.common.wrappers.gui;
|
||||
|
||||
import net.minecraft.client.gui.Font;
|
||||
#if PRE_MC_1_20_1
|
||||
#if MC_VER < MC_1_20_1
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
#else
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
@@ -24,14 +24,14 @@ public class DhScreen extends Screen
|
||||
// addButton in 1.16 and below
|
||||
protected Button addBtn(Button button)
|
||||
{
|
||||
#if PRE_MC_1_17_1
|
||||
#if MC_VER < MC_1_17_1
|
||||
return this.addButton(button);
|
||||
#else
|
||||
return this.addRenderableWidget(button);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if PRE_MC_1_20_1
|
||||
#if MC_VER < MC_1_20_1
|
||||
protected void DhDrawCenteredString(PoseStack guiStack, Font font, Component text, int x, int y, int color)
|
||||
{
|
||||
drawCenteredString(guiStack, font, text, x, y, color);
|
||||
|
||||
@@ -5,7 +5,7 @@ import net.minecraft.client.gui.components.Button;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.chat.MutableComponent;
|
||||
|
||||
#if PRE_MC_1_19_2
|
||||
#if MC_VER < MC_1_19_2
|
||||
import net.minecraft.network.chat.TextComponent;
|
||||
import net.minecraft.network.chat.TranslatableComponent;
|
||||
#endif
|
||||
@@ -17,7 +17,7 @@ public class GuiHelper
|
||||
*/
|
||||
public static Button MakeBtn(Component base, int a, int b, int c, int d, Button.OnPress action)
|
||||
{
|
||||
#if PRE_MC_1_19_4
|
||||
#if MC_VER < MC_1_19_4
|
||||
return new Button(a, b, c, d, base, action);
|
||||
#else
|
||||
return Button.builder(base, action).bounds(a, b, c, d).build();
|
||||
@@ -26,7 +26,7 @@ public class GuiHelper
|
||||
|
||||
public static MutableComponent TextOrLiteral(String text)
|
||||
{
|
||||
#if PRE_MC_1_19_2
|
||||
#if MC_VER < MC_1_19_2
|
||||
return new TextComponent(text);
|
||||
#else
|
||||
return Component.literal(text);
|
||||
@@ -35,7 +35,7 @@ public class GuiHelper
|
||||
|
||||
public static MutableComponent TextOrTranslatable(String text)
|
||||
{
|
||||
#if PRE_MC_1_19_2
|
||||
#if MC_VER < MC_1_19_2
|
||||
return new TextComponent(text);
|
||||
#else
|
||||
return Component.translatable(text);
|
||||
@@ -44,7 +44,7 @@ public class GuiHelper
|
||||
|
||||
public static MutableComponent Translatable(String text, Object... args)
|
||||
{
|
||||
#if PRE_MC_1_19_2
|
||||
#if MC_VER < MC_1_19_2
|
||||
return new TranslatableComponent(text, args);
|
||||
#else
|
||||
return Component.translatable(text, args);
|
||||
@@ -53,7 +53,7 @@ public class GuiHelper
|
||||
|
||||
public static void SetX(AbstractWidget w, int x)
|
||||
{
|
||||
#if PRE_MC_1_19_4
|
||||
#if MC_VER < MC_1_19_4
|
||||
w.x = x;
|
||||
#else
|
||||
w.setX(x);
|
||||
@@ -62,7 +62,7 @@ public class GuiHelper
|
||||
|
||||
public static void SetY(AbstractWidget w, int y)
|
||||
{
|
||||
#if PRE_MC_1_19_4
|
||||
#if MC_VER < MC_1_19_4
|
||||
w.y = y;
|
||||
#else
|
||||
w.setY(y);
|
||||
|
||||
+13
-9
@@ -4,7 +4,7 @@ import com.mojang.blaze3d.platform.Window;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.seibel.distanthorizons.core.config.gui.AbstractScreen;
|
||||
import net.minecraft.client.Minecraft;
|
||||
#if POST_MC_1_20_1
|
||||
#if MC_VER >= MC_1_20_1
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
#endif
|
||||
import net.minecraft.client.gui.components.ContainerObjectSelectionList;
|
||||
@@ -28,7 +28,7 @@ public class MinecraftScreen
|
||||
private AbstractScreen screen;
|
||||
|
||||
|
||||
#if PRE_MC_1_19_2
|
||||
#if MC_VER < MC_1_19_2
|
||||
public static net.minecraft.network.chat.TranslatableComponent translate(String str, Object... args)
|
||||
{
|
||||
return new net.minecraft.network.chat.TranslatableComponent(str, args);
|
||||
@@ -59,23 +59,23 @@ public class MinecraftScreen
|
||||
screen.scaledHeight = this.height;
|
||||
screen.init(); // Init our own config screen
|
||||
|
||||
this.list = new ConfigListWidget(this.minecraft, this.width, this.height, 0, this.height, 25); // Select the area to tint
|
||||
this.list = new ConfigListWidget(this.minecraft, this.width, this.height, 0, 0, 25); // Select the area to tint
|
||||
if (this.minecraft != null && this.minecraft.level != null) // Check if in game
|
||||
this.list.setRenderBackground(false); // Disable from rendering
|
||||
this.addWidget(this.list); // Add the tint to the things to be rendered
|
||||
}
|
||||
|
||||
@Override
|
||||
#if PRE_MC_1_20_1
|
||||
#if MC_VER < MC_1_20_1
|
||||
public void render(PoseStack matrices, int mouseX, int mouseY, float delta)
|
||||
#else
|
||||
public void render(GuiGraphics matrices, int mouseX, int mouseY, float delta)
|
||||
#endif
|
||||
{
|
||||
#if MC_1_20_2
|
||||
this.renderBackground(matrices, mouseX, mouseY, delta); // Render background
|
||||
#else
|
||||
#if MC_VER < MC_1_20_2
|
||||
this.renderBackground(matrices); // Render background
|
||||
#else
|
||||
this.renderBackground(matrices, mouseX, mouseY, delta); // Render background
|
||||
#endif
|
||||
this.list.render(matrices, mouseX, mouseY, delta); // Renders the items in the render list (currently only used to tint background darker)
|
||||
|
||||
@@ -131,9 +131,13 @@ public class MinecraftScreen
|
||||
|
||||
public static class ConfigListWidget extends ContainerObjectSelectionList
|
||||
{
|
||||
public ConfigListWidget(Minecraft minecraftClient, int i, int j, int k, int l, int m)
|
||||
public ConfigListWidget(Minecraft minecraftClient, int canvasWidth, int canvasHeight, int topMargin, int botMargin, int itemSpacing)
|
||||
{
|
||||
super(minecraftClient, i, j, k, l, m);
|
||||
#if MC_VER < MC_1_20_4
|
||||
super(minecraftClient, canvasWidth, canvasHeight, topMargin, canvasHeight - botMargin, itemSpacing);
|
||||
#else
|
||||
super(minecraftClient, canvasWidth, canvasHeight - (topMargin + botMargin), topMargin, itemSpacing);
|
||||
#endif
|
||||
this.centerListVertically = false;
|
||||
}
|
||||
|
||||
|
||||
+11
-11
@@ -34,17 +34,17 @@ import net.minecraft.client.gui.components.ImageButton;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
|
||||
#if POST_MC_1_17_1
|
||||
#if MC_VER >= MC_1_17_1
|
||||
import net.minecraft.client.renderer.GameRenderer;
|
||||
#endif
|
||||
#if PRE_MC_1_20_1
|
||||
#if MC_VER < MC_1_20_1
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import net.minecraft.client.Minecraft;
|
||||
#else
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
#endif
|
||||
|
||||
#if PRE_MC_1_20_2
|
||||
#if MC_VER < MC_1_20_2
|
||||
public class TexturedButtonWidget extends ImageButton
|
||||
#else
|
||||
public class TexturedButtonWidget extends Button
|
||||
@@ -52,7 +52,7 @@ public class TexturedButtonWidget extends Button
|
||||
{
|
||||
public final boolean renderBackground;
|
||||
|
||||
#if POST_MC_1_20_2
|
||||
#if MC_VER >= MC_1_20_2
|
||||
private final int u;
|
||||
private final int v;
|
||||
private final int hoveredVOffset;
|
||||
@@ -69,7 +69,7 @@ public class TexturedButtonWidget extends Button
|
||||
}
|
||||
public TexturedButtonWidget(int x, int y, int width, int height, int u, int v, int hoveredVOffset, ResourceLocation texture, int textureWidth, int textureHeight, OnPress pressAction, Component text, boolean renderBackground)
|
||||
{
|
||||
#if PRE_MC_1_20_2
|
||||
#if MC_VER < MC_1_20_2
|
||||
super(x, y, width, height, u, v, hoveredVOffset, texture, textureWidth, textureHeight, pressAction, text);
|
||||
#else
|
||||
// We don't pass on the text option as otherwise it will render (we normally pass it for narration)
|
||||
@@ -89,13 +89,13 @@ public class TexturedButtonWidget extends Button
|
||||
this.renderBackground = renderBackground;
|
||||
}
|
||||
|
||||
#if PRE_MC_1_20_2
|
||||
#if PRE_MC_1_19_4
|
||||
#if MC_VER < MC_1_20_2
|
||||
#if MC_VER < MC_1_19_4
|
||||
@Override
|
||||
public void renderButton(PoseStack matrices, int mouseX, int mouseY, float delta) {
|
||||
if (this.renderBackground) // Renders the background of the button
|
||||
{
|
||||
#if PRE_MC_1_17_1
|
||||
#if MC_VER < MC_1_17_1
|
||||
Minecraft.getInstance().getTextureManager().bind(WIDGETS_LOCATION);
|
||||
RenderSystem.color4f(1.0F, 1.0F, 1.0F, this.alpha);
|
||||
#else
|
||||
@@ -108,7 +108,7 @@ public class TexturedButtonWidget extends Button
|
||||
RenderSystem.enableBlend();
|
||||
RenderSystem.defaultBlendFunc();
|
||||
RenderSystem.enableDepthTest();
|
||||
#if PRE_MC_1_19_4
|
||||
#if MC_VER < MC_1_19_4
|
||||
this.blit(matrices, this.x, this.y, 0, 46 + i * 20, this.width / 2, this.height);
|
||||
this.blit(matrices, this.x + this.width / 2, this.y, 200 - this.width / 2, 46 + i * 20, this.width / 2, this.height);
|
||||
#else
|
||||
@@ -120,7 +120,7 @@ public class TexturedButtonWidget extends Button
|
||||
super.renderButton(matrices, mouseX, mouseY, delta);
|
||||
}
|
||||
#else
|
||||
#if PRE_MC_1_20_1
|
||||
#if MC_VER < MC_1_20_1
|
||||
@Override
|
||||
public void renderWidget(PoseStack matrices, int mouseX, int mouseY, float delta)
|
||||
{
|
||||
@@ -138,7 +138,7 @@ public class TexturedButtonWidget extends Button
|
||||
if (!this.active) i = 0;
|
||||
else if (this.isHovered) i = 2;
|
||||
|
||||
#if PRE_MC_1_20_1
|
||||
#if MC_VER < MC_1_20_1
|
||||
RenderSystem.enableBlend();
|
||||
RenderSystem.defaultBlendFunc();
|
||||
RenderSystem.enableDepthTest();
|
||||
|
||||
+16
-12
@@ -15,11 +15,11 @@ import net.minecraft.client.gui.components.events.GuiEventListener;
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
import net.minecraft.network.chat.Component;
|
||||
|
||||
#if POST_MC_1_17_1
|
||||
#if MC_VER >= MC_1_17_1
|
||||
import net.minecraft.client.gui.narration.NarratableEntry;
|
||||
#endif
|
||||
|
||||
#if PRE_MC_1_20_1
|
||||
#if MC_VER < MC_1_20_1
|
||||
import net.minecraft.client.gui.GuiComponent;
|
||||
#else
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
@@ -134,7 +134,7 @@ public class ChangelogScreen extends DhScreen
|
||||
);
|
||||
|
||||
|
||||
this.changelogArea = new TextArea(this.minecraft, this.width * 2, this.height, 32, this.height - 32, 10);
|
||||
this.changelogArea = new TextArea(this.minecraft, this.width * 2, this.height, 32, 32, 10);
|
||||
for (int i = 0; i < changelog.size(); i++)
|
||||
{
|
||||
this.changelogArea.addButton(TextOrLiteral(changelog.get(i)));
|
||||
@@ -144,16 +144,16 @@ public class ChangelogScreen extends DhScreen
|
||||
}
|
||||
|
||||
@Override
|
||||
#if PRE_MC_1_20_1
|
||||
#if MC_VER < MC_1_20_1
|
||||
public void render(PoseStack matrices, int mouseX, int mouseY, float delta)
|
||||
#else
|
||||
public void render(GuiGraphics matrices, int mouseX, int mouseY, float delta)
|
||||
#endif
|
||||
{
|
||||
#if MC_1_20_2
|
||||
this.renderBackground(matrices, mouseX, mouseY, delta); // Render background
|
||||
#else
|
||||
#if MC_VER < MC_1_20_2
|
||||
this.renderBackground(matrices); // Render background
|
||||
#else
|
||||
this.renderBackground(matrices, mouseX, mouseY, delta); // Render background
|
||||
#endif
|
||||
if (!usable)
|
||||
return;
|
||||
@@ -161,7 +161,7 @@ public class ChangelogScreen extends DhScreen
|
||||
// Set the scroll position to the mouse height relative to the screen
|
||||
// This is a bit of a hack as we cannot scroll on this area
|
||||
double scrollAmount = ((double) mouseY) / ((double) this.height) * 1.1 * this.changelogArea.getMaxScroll();
|
||||
#if MC_1_16_5 || MC_1_17_1
|
||||
#if MC_VER == MC_1_16_5 || MC_VER == MC_1_17_1
|
||||
this.changelogArea.setScrollAmount(scrollAmount);
|
||||
#else
|
||||
this.changelogArea.scrollAmount = scrollAmount;
|
||||
@@ -185,9 +185,13 @@ public class ChangelogScreen extends DhScreen
|
||||
{
|
||||
Font textRenderer;
|
||||
|
||||
public TextArea(Minecraft minecraftClient, int i, int j, int k, int l, int m)
|
||||
public TextArea(Minecraft minecraftClient, int canvasWidth, int canvasHeight, int topMargin, int botMargin, int itemSpacing)
|
||||
{
|
||||
super(minecraftClient, i, j, k, l, m);
|
||||
#if MC_VER < MC_1_20_4
|
||||
super(minecraftClient, canvasWidth, canvasHeight, topMargin, canvasHeight - botMargin, itemSpacing);
|
||||
#else
|
||||
super(minecraftClient, canvasWidth, canvasHeight - (topMargin + botMargin), topMargin, itemSpacing);
|
||||
#endif
|
||||
this.centerListVertically = false;
|
||||
textRenderer = minecraftClient.font;
|
||||
}
|
||||
@@ -221,7 +225,7 @@ public class ChangelogScreen extends DhScreen
|
||||
return new ButtonEntry(text);
|
||||
}
|
||||
|
||||
#if PRE_MC_1_20_1
|
||||
#if MC_VER < MC_1_20_1
|
||||
@Override
|
||||
public void render(PoseStack matrices, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean hovered, float tickDelta)
|
||||
{
|
||||
@@ -240,7 +244,7 @@ public class ChangelogScreen extends DhScreen
|
||||
{
|
||||
return children;
|
||||
}
|
||||
#if POST_MC_1_17_1
|
||||
#if MC_VER >= MC_1_17_1
|
||||
@Override
|
||||
public List<? extends NarratableEntry> narratables()
|
||||
{
|
||||
|
||||
+6
-13
@@ -11,7 +11,7 @@ import com.seibel.distanthorizons.core.jar.JarUtils;
|
||||
import com.seibel.distanthorizons.core.jar.installer.ModrinthGetter;
|
||||
import com.seibel.distanthorizons.core.jar.updater.SelfUpdater;
|
||||
import net.minecraft.client.Minecraft;
|
||||
#if POST_MC_1_20_1
|
||||
#if MC_VER >= MC_1_20_1
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
#else
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
@@ -66,13 +66,6 @@ public class UpdateModScreen extends DhScreen
|
||||
|
||||
try
|
||||
{
|
||||
// We cannot get assets from the root of the mod so we use this hack
|
||||
// TODO: Load the icon.png and logo.png in the mod initialise rather than here
|
||||
ResourceLocation logoLocation = new ResourceLocation(ModInfo.ID, "logo.png");
|
||||
Minecraft.getInstance().getTextureManager().register(
|
||||
logoLocation,
|
||||
new DynamicTexture(NativeImage.read(JarUtils.accessFile("logo.png")))
|
||||
);
|
||||
|
||||
|
||||
// Logo image
|
||||
@@ -84,7 +77,7 @@ public class UpdateModScreen extends DhScreen
|
||||
// Offset
|
||||
0, 0,
|
||||
// Some textuary stuff
|
||||
0, logoLocation, 130, 65,
|
||||
0, new ResourceLocation(ModInfo.ID, "logo.png"), 130, 65,
|
||||
// Create the button and tell it where to go
|
||||
// For now it goes to the client option by default
|
||||
(buttonWidget) -> System.out.println("Nice, you found an easter egg :)"), // TODO: Add a proper easter egg to pressing the logo (maybe with confetti)
|
||||
@@ -146,16 +139,16 @@ public class UpdateModScreen extends DhScreen
|
||||
}
|
||||
|
||||
@Override
|
||||
#if PRE_MC_1_20_1
|
||||
#if MC_VER < MC_1_20_1
|
||||
public void render(PoseStack matrices, int mouseX, int mouseY, float delta)
|
||||
#else
|
||||
public void render(GuiGraphics matrices, int mouseX, int mouseY, float delta)
|
||||
#endif
|
||||
{
|
||||
#if MC_1_20_2
|
||||
this.renderBackground(matrices, mouseX, mouseY, delta); // Render background
|
||||
#else
|
||||
#if MC_VER < MC_1_20_2
|
||||
this.renderBackground(matrices); // Render background
|
||||
#else
|
||||
this.renderBackground(matrices, mouseX, mouseY, delta); // Render background
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
+7
-3
@@ -47,7 +47,7 @@ import net.minecraft.client.player.LocalPlayer;
|
||||
import net.minecraft.client.resources.model.ModelManager;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
#if PRE_MC_1_19_2
|
||||
#if MC_VER < MC_1_19_2
|
||||
import net.minecraft.network.chat.TextComponent;
|
||||
#endif
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
@@ -197,7 +197,7 @@ public class MinecraftClientWrapper implements IMinecraftClientWrapper, IMinecra
|
||||
@Override
|
||||
public DhChunkPos getPlayerChunkPos()
|
||||
{
|
||||
#if PRE_MC_1_17_1
|
||||
#if MC_VER < MC_1_17_1
|
||||
ChunkPos playerPos = new ChunkPos(getPlayer().blockPosition());
|
||||
#else
|
||||
ChunkPos playerPos = getPlayer().chunkPosition();
|
||||
@@ -262,7 +262,7 @@ public class MinecraftClientWrapper implements IMinecraftClientWrapper, IMinecra
|
||||
{
|
||||
LocalPlayer p = getPlayer();
|
||||
if (p == null) return;
|
||||
#if PRE_MC_1_19_2
|
||||
#if MC_VER < MC_1_19_2
|
||||
p.sendMessage(new TextComponent(string), getPlayer().getUUID());
|
||||
#else
|
||||
p.sendSystemMessage(net.minecraft.network.chat.Component.translatable(string));
|
||||
@@ -282,7 +282,11 @@ public class MinecraftClientWrapper implements IMinecraftClientWrapper, IMinecra
|
||||
{
|
||||
LOGGER.error(ModInfo.READABLE_NAME + " had the following error: [" + errorMessage + "]. Crashing Minecraft...", exception);
|
||||
CrashReport report = new CrashReport(errorMessage, exception);
|
||||
#if MC_VER < MC_1_20_4
|
||||
Minecraft.crash(report);
|
||||
#else
|
||||
Minecraft.getInstance().delayCrash(report);
|
||||
#endif
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+41
-28
@@ -21,6 +21,7 @@ package com.seibel.distanthorizons.common.wrappers.minecraft;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.nio.FloatBuffer;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
@@ -39,12 +40,13 @@ import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||
import com.seibel.distanthorizons.core.render.DhApiRenderProxy;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.misc.ILightMapWrapper;
|
||||
|
||||
#if PRE_MC_1_19_4
|
||||
import com.mojang.math.Vector3f;
|
||||
#if MC_VER < MC_1_19_4
|
||||
import org.joml.Vector3f;
|
||||
#else
|
||||
import org.joml.Matrix4f;
|
||||
import org.joml.Vector3f;
|
||||
#endif
|
||||
#if MC_1_20_2
|
||||
#if MC_VER >= MC_1_20_2
|
||||
import net.minecraft.client.renderer.chunk.SectionRenderDispatcher;
|
||||
#endif
|
||||
|
||||
@@ -67,7 +69,7 @@ import net.minecraft.client.renderer.FogRenderer;
|
||||
import net.minecraft.client.renderer.LevelRenderer;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.effect.MobEffects;
|
||||
#if PRE_MC_1_17_1
|
||||
#if MC_VER < MC_1_17_1
|
||||
import net.minecraft.tags.FluidTags;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.level.material.FluidState;
|
||||
@@ -78,6 +80,7 @@ import net.minecraft.world.level.material.FogType;
|
||||
import net.minecraft.world.phys.AABB;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.joml.Matrix4f;
|
||||
|
||||
|
||||
/**
|
||||
@@ -116,8 +119,7 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper
|
||||
public Vec3f getLookAtVector()
|
||||
{
|
||||
Camera camera = MC.gameRenderer.getMainCamera();
|
||||
Vector3f cameraDir = camera.getLookVector();
|
||||
return new Vec3f(cameraDir.x(), cameraDir.y(), cameraDir.z());
|
||||
return new Vec3f(camera.getLookVector().x(), camera.getLookVector().y(), camera.getLookVector().z());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -133,7 +135,7 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper
|
||||
public boolean playerHasBlindingEffect()
|
||||
{
|
||||
return MC.player.getActiveEffectsMap().get(MobEffects.BLINDNESS) != null
|
||||
#if POST_AND_MC_1_19_2
|
||||
#if MC_VER >= MC_1_19_2
|
||||
|| MC.player.getActiveEffectsMap().get(MobEffects.DARKNESS) != null // Deep dark effect
|
||||
#endif
|
||||
;
|
||||
@@ -148,10 +150,27 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper
|
||||
return new Vec3d(projectedView.x, projectedView.y, projectedView.z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mat4f getWorldViewMatrix()
|
||||
{
|
||||
Camera camera = MC.gameRenderer.getMainCamera();
|
||||
Vector3f cameraVec3 = new Vector3f(
|
||||
(float)camera.getPosition().x,
|
||||
(float)camera.getPosition().y,
|
||||
(float)camera.getPosition().z);
|
||||
cameraVec3 = cameraVec3.negate();
|
||||
|
||||
Matrix4f matWorldView = new Matrix4f()
|
||||
.rotateX((float)Math.toRadians(camera.getXRot()))
|
||||
.rotateY((float)Math.toRadians(camera.getYRot() + 180f))
|
||||
.translate(cameraVec3);
|
||||
return new Mat4f(matWorldView);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mat4f getDefaultProjectionMatrix(float partialTicks)
|
||||
{
|
||||
#if PRE_MC_1_17_1
|
||||
#if MC_VER < MC_1_17_1
|
||||
return McObjectConverter.Convert(Minecraft.getInstance().gameRenderer.getProjectionMatrix(Minecraft.getInstance().gameRenderer.getMainCamera(), partialTicks, true));
|
||||
#else
|
||||
return McObjectConverter.Convert(MC.gameRenderer.getProjectionMatrix(MC.gameRenderer.getFov(MC.gameRenderer.getMainCamera(), partialTicks, true)));
|
||||
@@ -161,7 +180,7 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper
|
||||
@Override
|
||||
public double getGamma()
|
||||
{
|
||||
#if PRE_MC_1_19_2
|
||||
#if MC_VER < MC_1_19_2
|
||||
return MC.options.gamma;
|
||||
#else
|
||||
return MC.options.gamma().get();
|
||||
@@ -171,7 +190,7 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper
|
||||
@Override
|
||||
public Color getFogColor(float partialTicks)
|
||||
{
|
||||
#if PRE_MC_1_17_1
|
||||
#if MC_VER < MC_1_17_1
|
||||
float[] colorValues = new float[4];
|
||||
GL15.glGetFloatv(GL15.GL_FOG_COLOR, colorValues);
|
||||
#else
|
||||
@@ -192,7 +211,7 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper
|
||||
{
|
||||
if (MC.level.dimensionType().hasSkyLight())
|
||||
{
|
||||
#if PRE_MC_1_17_1
|
||||
#if MC_VER < MC_1_17_1
|
||||
Vec3 colorValues = MC.level.getSkyColor(MC.gameRenderer.getMainCamera().getBlockPosition(), MC.getFrameTime());
|
||||
#else
|
||||
Vec3 colorValues = MC.level.getSkyColor(MC.gameRenderer.getMainCamera().getPosition(), MC.getFrameTime());
|
||||
@@ -213,7 +232,7 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper
|
||||
@Override
|
||||
public int getRenderDistance()
|
||||
{
|
||||
#if PRE_MC_1_18_2
|
||||
#if MC_VER < MC_1_18_2
|
||||
//FIXME: How to resolve this?
|
||||
return MC.options.renderDistance;
|
||||
#else
|
||||
@@ -261,12 +280,6 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper
|
||||
@Override
|
||||
public int getTargetFrameBuffer()
|
||||
{
|
||||
int frameBufferOverrideId = DhApiRenderProxy.INSTANCE.targetFrameBufferOverride;
|
||||
if (frameBufferOverrideId != -1)
|
||||
{
|
||||
return frameBufferOverrideId;
|
||||
}
|
||||
|
||||
// used so we can access the framebuffer shaders end up rendering to
|
||||
if (AbstractOptifineAccessor.optifinePresent())
|
||||
{
|
||||
@@ -321,25 +334,25 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper
|
||||
{
|
||||
try
|
||||
{
|
||||
#if MC_1_20_2
|
||||
#if MC_VER < MC_1_20_2
|
||||
LevelRenderer levelRenderer = MC.levelRenderer;
|
||||
Collection<SectionRenderDispatcher.RenderSection> chunks = levelRenderer.visibleSections;
|
||||
Collection<LevelRenderer.RenderChunkInfo> chunks =
|
||||
#if MC_VER < MC_1_18_2 levelRenderer.renderChunks;
|
||||
#else levelRenderer.renderChunkStorage.get().renderChunks; #endif
|
||||
|
||||
return (chunks.stream().map((chunk) -> {
|
||||
AABB chunkBoundingBox = chunk.getBoundingBox();
|
||||
AABB chunkBoundingBox =
|
||||
#if MC_VER < MC_1_18_2 chunk.chunk.bb;
|
||||
#else chunk.chunk.getBoundingBox(); #endif
|
||||
return new DhChunkPos(Math.floorDiv((int) chunkBoundingBox.minX, 16),
|
||||
Math.floorDiv((int) chunkBoundingBox.minZ, 16));
|
||||
}).collect(Collectors.toCollection(HashSet::new)));
|
||||
#else
|
||||
LevelRenderer levelRenderer = MC.levelRenderer;
|
||||
Collection<LevelRenderer.RenderChunkInfo> chunks =
|
||||
#if PRE_MC_1_18_2 levelRenderer.renderChunks;
|
||||
#else levelRenderer.renderChunkStorage.get().renderChunks; #endif
|
||||
Collection<SectionRenderDispatcher.RenderSection> chunks = levelRenderer.visibleSections;
|
||||
|
||||
return (chunks.stream().map((chunk) -> {
|
||||
AABB chunkBoundingBox =
|
||||
#if PRE_MC_1_18_2 chunk.chunk.bb;
|
||||
#else chunk.chunk.getBoundingBox(); #endif
|
||||
AABB chunkBoundingBox = chunk.getBoundingBox();
|
||||
return new DhChunkPos(Math.floorDiv((int) chunkBoundingBox.minX, 16),
|
||||
Math.floorDiv((int) chunkBoundingBox.minZ, 16));
|
||||
}).collect(Collectors.toCollection(HashSet::new)));
|
||||
@@ -371,7 +384,7 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper
|
||||
@Override
|
||||
public boolean isFogStateSpecial()
|
||||
{
|
||||
#if PRE_MC_1_17_1
|
||||
#if MC_VER < MC_1_17_1
|
||||
Camera camera = Minecraft.getInstance().gameRenderer.getMainCamera();
|
||||
FluidState fluidState = camera.getFluidInCamera();
|
||||
Entity entity = camera.getEntity();
|
||||
|
||||
+18
-17
@@ -25,35 +25,39 @@ import org.lwjgl.opengl.GL32;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
/**
|
||||
* @author James Seibel
|
||||
* @version 11-21-2021
|
||||
*/
|
||||
public class LightMapWrapper implements ILightMapWrapper
|
||||
{
|
||||
private int textureId = 0;
|
||||
|
||||
public LightMapWrapper()
|
||||
{
|
||||
}
|
||||
|
||||
//==============//
|
||||
// constructors //
|
||||
//==============//
|
||||
|
||||
public LightMapWrapper() { }
|
||||
|
||||
private void createLightmap(NativeImage image)
|
||||
{
|
||||
textureId = GL32.glGenTextures();
|
||||
GL32.glBindTexture(GL32.GL_TEXTURE_2D, textureId);
|
||||
this.textureId = GL32.glGenTextures();
|
||||
GL32.glBindTexture(GL32.GL_TEXTURE_2D, this.textureId);
|
||||
GL32.glTexImage2D(GL32.GL_TEXTURE_2D, 0, image.format().glFormat(), image.getWidth(), image.getHeight(),
|
||||
0, image.format().glFormat(), GL32.GL_UNSIGNED_BYTE, (ByteBuffer) null);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//=========//
|
||||
// methods //
|
||||
//=========//
|
||||
|
||||
public void uploadLightmap(NativeImage image)
|
||||
{
|
||||
int currentBind = GL32.glGetInteger(GL32.GL_TEXTURE_BINDING_2D);
|
||||
GL32.glBindTexture(GL32.GL_TEXTURE_2D, textureId);
|
||||
if (textureId == 0)
|
||||
GL32.glBindTexture(GL32.GL_TEXTURE_2D, this.textureId);
|
||||
if (this.textureId == 0)
|
||||
{
|
||||
createLightmap(image);
|
||||
this.createLightmap(image);
|
||||
}
|
||||
// NativeImage::upload(int levelOfDetail, int xOffset, int yOffset, bool shouldCleanup?)
|
||||
image.upload(0, 0, 0, false);
|
||||
GL32.glBindTexture(GL32.GL_TEXTURE_2D, currentBind);
|
||||
}
|
||||
@@ -66,9 +70,6 @@ public class LightMapWrapper implements ILightMapWrapper
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unbind()
|
||||
{
|
||||
GL32.glBindTexture(GL32.GL_TEXTURE_2D, 0);
|
||||
}
|
||||
public void unbind() { GL32.glBindTexture(GL32.GL_TEXTURE_2D, 0); }
|
||||
|
||||
}
|
||||
|
||||
+1
-1
@@ -33,7 +33,7 @@ public class ServerPlayerWrapper implements IServerPlayerWrapper
|
||||
|
||||
public IServerLevelWrapper getLevel()
|
||||
{
|
||||
#if PRE_MC_1_20_1
|
||||
#if MC_VER < MC_1_20_1
|
||||
return ServerLevelWrapper.getWrapper(this.serverPlayer.getLevel());
|
||||
#else
|
||||
return ServerLevelWrapper.getWrapper(this.serverPlayer.serverLevel());
|
||||
|
||||
+10
-6
@@ -27,6 +27,7 @@ import net.minecraft.world.level.chunk.ChunkAccess;
|
||||
import net.minecraft.world.level.chunk.ChunkSource;
|
||||
import net.minecraft.world.level.chunk.ChunkStatus;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
@@ -54,8 +55,14 @@ public class ClientLevelWrapper implements IClientLevelWrapper
|
||||
// wrapper logic //
|
||||
//===============//
|
||||
|
||||
public static IClientLevelWrapper getWrapper(ClientLevel level)
|
||||
@Nullable
|
||||
public static IClientLevelWrapper getWrapper(@Nullable ClientLevel level)
|
||||
{
|
||||
if (level == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
// used if the client is connected to a server that defines the currently loaded level
|
||||
if (KEYED_CLIENT_LEVEL_MANAGER.getUseOverrideWrapper())
|
||||
{
|
||||
@@ -64,10 +71,7 @@ public class ClientLevelWrapper implements IClientLevelWrapper
|
||||
|
||||
return getWrapperIgnoringOverride(level);
|
||||
}
|
||||
public static IClientLevelWrapper getWrapperIgnoringOverride(ClientLevel level)
|
||||
{
|
||||
return LEVEL_WRAPPER_BY_CLIENT_LEVEL.computeIfAbsent(level, ClientLevelWrapper::new);
|
||||
}
|
||||
public static IClientLevelWrapper getWrapperIgnoringOverride(@NotNull ClientLevel level) { return LEVEL_WRAPPER_BY_CLIENT_LEVEL.computeIfAbsent(level, ClientLevelWrapper::new); }
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
@@ -132,7 +136,7 @@ public class ClientLevelWrapper implements IClientLevelWrapper
|
||||
@Override
|
||||
public int getMinHeight()
|
||||
{
|
||||
#if PRE_MC_1_17_1
|
||||
#if MC_VER < MC_1_17_1
|
||||
return 0;
|
||||
#else
|
||||
return this.level.getMinBuildHeight();
|
||||
|
||||
+1
-1
@@ -130,7 +130,7 @@ public class ServerLevelWrapper implements IServerLevelWrapper
|
||||
@Override
|
||||
public int getMinHeight()
|
||||
{
|
||||
#if PRE_MC_1_17_1
|
||||
#if MC_VER < MC_1_17_1
|
||||
return 0;
|
||||
#else
|
||||
return level.getMinBuildHeight();
|
||||
|
||||
+65
-18
@@ -56,7 +56,7 @@ import com.seibel.distanthorizons.common.wrappers.worldGeneration.step.StepStruc
|
||||
import com.seibel.distanthorizons.common.wrappers.worldGeneration.step.StepStructureStart;
|
||||
import com.seibel.distanthorizons.common.wrappers.worldGeneration.step.StepSurface;
|
||||
|
||||
#if POST_MC_1_19_4
|
||||
#if MC_VER >= MC_1_19_4
|
||||
import net.minecraft.core.registries.Registries;
|
||||
#else
|
||||
import net.minecraft.core.Registry;
|
||||
@@ -70,6 +70,7 @@ import net.minecraft.world.level.chunk.ChunkStatus;
|
||||
import net.minecraft.world.level.chunk.LevelChunk;
|
||||
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.RegionFileStorage;
|
||||
import net.minecraft.world.level.levelgen.DebugLevelSource;
|
||||
import net.minecraft.world.level.levelgen.FlatLevelSource;
|
||||
@@ -365,9 +366,9 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
|
||||
private static ProtoChunk EmptyChunk(ServerLevel level, ChunkPos chunkPos)
|
||||
{
|
||||
return new ProtoChunk(chunkPos, UpgradeData.EMPTY
|
||||
#if POST_MC_1_17_1 , level #endif
|
||||
#if POST_MC_1_18_2 , level.registryAccess().registryOrThrow(
|
||||
#if PRE_MC_1_19_4
|
||||
#if MC_VER >= MC_1_17_1 , level #endif
|
||||
#if MC_VER >= MC_1_18_2 , level.registryAccess().registryOrThrow(
|
||||
#if MC_VER < MC_1_19_4
|
||||
Registry.BIOME_REGISTRY
|
||||
#else
|
||||
Registries.BIOME
|
||||
@@ -381,22 +382,50 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
|
||||
{
|
||||
ServerLevel level = this.params.level;
|
||||
|
||||
|
||||
|
||||
//====================//
|
||||
// get the chunk data //
|
||||
//====================//
|
||||
|
||||
CompoundTag chunkData = null;
|
||||
try
|
||||
{
|
||||
// Warning: if multiple threads attempt to access this method at the same time,
|
||||
// it can throw EOFExceptions that are caught and logged by Minecraft
|
||||
//chunkData = level.getChunkSource().chunkMap.readChunk(chunkPos);
|
||||
IOWorker ioWorker = level.getChunkSource().chunkMap.worker;
|
||||
|
||||
RegionFileStorage storage = this.params.level.getChunkSource().chunkMap.worker.storage;
|
||||
RegionFileStorageExternalCache cache = this.getOrCreateRegionFileCache(storage);
|
||||
chunkData = cache.read(chunkPos);
|
||||
#if MC_VER <= MC_1_18_2
|
||||
chunkData = ioWorker.load(chunkPos);
|
||||
#else
|
||||
|
||||
// timeout should prevent locking up the thread if the ioWorker dies or has issues
|
||||
int maxGetTimeInSec = Config.Client.Advanced.WorldGenerator.worldGenerationTimeoutLengthInSeconds.get();
|
||||
CompletableFuture<Optional<CompoundTag>> future = ioWorker.loadAsync(chunkPos);
|
||||
try
|
||||
{
|
||||
Optional<CompoundTag> data = future.get(maxGetTimeInSec, TimeUnit.SECONDS);
|
||||
if (data.isPresent())
|
||||
{
|
||||
chunkData = data.get();
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LOAD_LOGGER.warn("Unable to get chunk at pos ["+chunkPos+"] after ["+maxGetTimeInSec+"] milliseconds.", e);
|
||||
future.cancel(true);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LOAD_LOGGER.error("DistantHorizons: Couldn't load or make chunk " + chunkPos + ". Error: " + e.getMessage(), e);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//========================//
|
||||
// convert the chunk data //
|
||||
//========================//
|
||||
|
||||
if (chunkData == null)
|
||||
{
|
||||
return EmptyChunk(level, chunkPos);
|
||||
@@ -405,12 +434,18 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
|
||||
{
|
||||
try
|
||||
{
|
||||
LOAD_LOGGER.info("DistantHorizons: Loading chunk " + chunkPos + " from disk.");
|
||||
LOAD_LOGGER.info("DistantHorizons: Loading chunk [" + chunkPos + "] from disk.");
|
||||
return ChunkLoader.read(level, chunkPos, chunkData);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LOAD_LOGGER.error("DistantHorizons: Couldn't load or make chunk " + chunkPos + ". Returning an empty chunk. Error: " + e.getMessage(), e);
|
||||
LOAD_LOGGER.error(
|
||||
"DistantHorizons: couldn't load or make chunk at ["+chunkPos+"]." +
|
||||
"Please try optimizing your world to fix this issue. \n" +
|
||||
"World optimization can be done from the singleplayer world selection screen.\n" +
|
||||
"Error: ["+e.getMessage()+"]."
|
||||
, e);
|
||||
|
||||
return EmptyChunk(level, chunkPos);
|
||||
}
|
||||
}
|
||||
@@ -463,8 +498,8 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
|
||||
if (target == null)
|
||||
{
|
||||
target = new ProtoChunk(chunkPos, UpgradeData.EMPTY
|
||||
#if POST_MC_1_17_1 , params.level #endif
|
||||
#if POST_MC_1_18_2 , params.biomes, null #endif
|
||||
#if MC_VER >= MC_1_17_1 , params.level #endif
|
||||
#if MC_VER >= MC_1_18_2 , params.biomes, null #endif
|
||||
);
|
||||
}
|
||||
return target;
|
||||
@@ -507,7 +542,7 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
|
||||
ChunkAccess target = wrappedChunk.getChunk();
|
||||
if (target instanceof LevelChunk)
|
||||
{
|
||||
#if MC_1_16_5 || MC_1_17_1
|
||||
#if MC_VER == MC_1_16_5 || MC_VER == MC_1_17_1
|
||||
((LevelChunk) target).setLoaded(true);
|
||||
#else
|
||||
((LevelChunk) target).loaded = true;
|
||||
@@ -520,7 +555,7 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
|
||||
}
|
||||
|
||||
boolean isFull = target.getStatus() == ChunkStatus.FULL || target instanceof LevelChunk;
|
||||
#if POST_MC_1_18_2
|
||||
#if MC_VER >= MC_1_18_2
|
||||
boolean isPartial = target.isOldNoiseGeneration();
|
||||
#endif
|
||||
if (isFull)
|
||||
@@ -528,7 +563,7 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
|
||||
LOAD_LOGGER.info("Detected full existing chunk at {}", target.getPos());
|
||||
genEvent.resultConsumer.accept(wrappedChunk);
|
||||
}
|
||||
#if POST_MC_1_18_2
|
||||
#if MC_VER >= MC_1_18_2
|
||||
else if (isPartial)
|
||||
{
|
||||
LOAD_LOGGER.info("Detected old existing chunk at {}", target.getPos());
|
||||
@@ -648,7 +683,19 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
|
||||
|
||||
int maxSkyLight = this.serverlevel.getServerLevelWrapper().hasSkyLight() ? 15 : 0;
|
||||
|
||||
ArrayList<IChunkWrapper> iChunkWrapperList = new ArrayList<>(chunksToGenerate);
|
||||
// only light generated chunks,
|
||||
// attempting to light un-generated chunks will cause lighting issues on bordering generated chunks
|
||||
ArrayList<IChunkWrapper> iChunkWrapperList = new ArrayList<>();
|
||||
for (int i = 0; i < chunksToGenerate.size(); i++) // regular for loop since enhanced for loops increase GC pressure slightly
|
||||
{
|
||||
ChunkWrapper chunkWrapper = chunksToGenerate.get(i);
|
||||
if (chunkWrapper.getChunk().getStatus() != ChunkStatus.EMPTY)
|
||||
{
|
||||
iChunkWrapperList.add(chunkWrapper);
|
||||
}
|
||||
}
|
||||
|
||||
// light each chunk in the list
|
||||
for (int i = 0; i < iChunkWrapperList.size(); i++)
|
||||
{
|
||||
IChunkWrapper centerChunk = iChunkWrapperList.get(i);
|
||||
|
||||
+9
-9
@@ -31,16 +31,16 @@ import net.minecraft.server.level.ThreadedLevelLightEngine;
|
||||
import net.minecraft.world.level.biome.Biome;
|
||||
import net.minecraft.world.level.biome.BiomeManager;
|
||||
import net.minecraft.world.level.chunk.ChunkGenerator;
|
||||
#if POST_MC_1_18_2
|
||||
#if MC_VER >= MC_1_18_2
|
||||
import net.minecraft.world.level.chunk.storage.ChunkScanAccess;
|
||||
#endif
|
||||
import net.minecraft.world.level.levelgen.WorldGenSettings;
|
||||
#if PRE_MC_1_19_2
|
||||
#if MC_VER < MC_1_19_2
|
||||
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureManager;
|
||||
#else
|
||||
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplateManager;
|
||||
import net.minecraft.world.level.levelgen.RandomState;
|
||||
#if POST_MC_1_19_4
|
||||
#if MC_VER >= MC_1_19_4
|
||||
import net.minecraft.world.level.levelgen.WorldOptions;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
#endif
|
||||
@@ -50,13 +50,13 @@ import net.minecraft.world.level.storage.WorldData;
|
||||
public final class GlobalParameters
|
||||
{
|
||||
public final ChunkGenerator generator;
|
||||
#if PRE_MC_1_19_2
|
||||
#if MC_VER < MC_1_19_2
|
||||
public final StructureManager structures;
|
||||
#else
|
||||
public final StructureTemplateManager structures;
|
||||
public final RandomState randomState;
|
||||
#endif
|
||||
#if PRE_MC_1_19_4
|
||||
#if MC_VER < MC_1_19_4
|
||||
public final WorldGenSettings worldGenSettings;
|
||||
#else
|
||||
public final WorldOptions worldOptions;
|
||||
@@ -67,7 +67,7 @@ public final class GlobalParameters
|
||||
public final RegistryAccess registry;
|
||||
public final long worldSeed;
|
||||
public final DataFixer fixerUpper;
|
||||
#if POST_MC_1_18_2
|
||||
#if MC_VER >= MC_1_18_2
|
||||
public final BiomeManager biomeManager;
|
||||
public final ChunkScanAccess chunkScanner; // FIXME: Figure out if this is actually needed
|
||||
#endif
|
||||
@@ -81,7 +81,7 @@ public final class GlobalParameters
|
||||
WorldData worldData = server.getWorldData();
|
||||
registry = server.registryAccess();
|
||||
|
||||
#if PRE_MC_1_19_4
|
||||
#if MC_VER < MC_1_19_4
|
||||
worldGenSettings = worldData.worldGenSettings();
|
||||
biomes = registry.registryOrThrow(Registry.BIOME_REGISTRY);
|
||||
worldSeed = worldGenSettings.seed();
|
||||
@@ -90,14 +90,14 @@ public final class GlobalParameters
|
||||
biomes = registry.registryOrThrow(Registries.BIOME);
|
||||
worldSeed = worldOptions.seed();
|
||||
#endif
|
||||
#if POST_MC_1_18_2
|
||||
#if MC_VER >= MC_1_18_2
|
||||
biomeManager = new BiomeManager(level, BiomeManager.obfuscateSeed(worldSeed));
|
||||
chunkScanner = level.getChunkSource().chunkScanner();
|
||||
#endif
|
||||
structures = server.getStructureManager();
|
||||
generator = level.getChunkSource().getGenerator();
|
||||
fixerUpper = server.getFixerUpper();
|
||||
#if POST_MC_1_19_2
|
||||
#if MC_VER >= MC_1_19_2
|
||||
randomState = level.getChunkSource().randomState();
|
||||
#endif
|
||||
}
|
||||
|
||||
+7
-7
@@ -25,7 +25,7 @@ import com.seibel.distanthorizons.common.wrappers.worldGeneration.mimicObject.Wo
|
||||
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.world.level.WorldGenLevel;
|
||||
#if POST_MC_1_18_2
|
||||
#if MC_VER >= MC_1_18_2
|
||||
import net.minecraft.world.level.levelgen.structure.StructureCheck;
|
||||
#endif
|
||||
|
||||
@@ -35,7 +35,7 @@ public final class ThreadedParameters
|
||||
|
||||
final ServerLevel level;
|
||||
public WorldGenStructFeatManager structFeat = null;
|
||||
#if POST_MC_1_18_2
|
||||
#if MC_VER >= MC_1_18_2
|
||||
public StructureCheck structCheck;
|
||||
#endif
|
||||
boolean isValid = true;
|
||||
@@ -63,9 +63,9 @@ public final class ThreadedParameters
|
||||
previousGlobalParameters = param;
|
||||
|
||||
this.level = param.level;
|
||||
#if PRE_MC_1_18_2
|
||||
#if MC_VER < MC_1_18_2
|
||||
this.structFeat = new WorldGenStructFeatManager(param.worldGenSettings, level);
|
||||
#elif PRE_MC_1_19_2
|
||||
#elif MC_VER < MC_1_19_2
|
||||
this.structCheck = this.createStructureCheck(param);
|
||||
#else
|
||||
this.structCheck = new StructureCheck(param.chunkScanner, param.registry, param.structures,
|
||||
@@ -80,15 +80,15 @@ public final class ThreadedParameters
|
||||
|
||||
public void makeStructFeat(WorldGenLevel genLevel, GlobalParameters param)
|
||||
{
|
||||
#if PRE_MC_1_19_4
|
||||
structFeat = new WorldGenStructFeatManager(param.worldGenSettings, genLevel #if POST_MC_1_18_2 , structCheck #endif );
|
||||
#if MC_VER < MC_1_19_4
|
||||
structFeat = new WorldGenStructFeatManager(param.worldGenSettings, genLevel #if MC_VER >= MC_1_18_2 , structCheck #endif );
|
||||
#else
|
||||
structFeat = new WorldGenStructFeatManager(param.worldOptions, genLevel, structCheck);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#if POST_MC_1_18_2 && PRE_MC_1_19_2
|
||||
#if MC_VER >= MC_1_18_2 && MC_VER < MC_1_19_2
|
||||
public void recreateStructureCheck()
|
||||
{
|
||||
if (previousGlobalParameters != null)
|
||||
|
||||
+57
-31
@@ -37,7 +37,7 @@ import java.util.Objects;
|
||||
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.core.SectionPos;
|
||||
#if POST_MC_1_19_4
|
||||
#if MC_VER >= MC_1_19_4
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
#endif
|
||||
@@ -55,24 +55,24 @@ import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.chunk.*;
|
||||
import net.minecraft.world.level.chunk.storage.ChunkSerializer;
|
||||
import net.minecraft.world.level.levelgen.Heightmap;
|
||||
#if POST_MC_1_18_2
|
||||
#if MC_VER >= MC_1_18_2
|
||||
import net.minecraft.world.level.levelgen.blending.BlendingData;
|
||||
#if PRE_MC_1_19_2
|
||||
#if MC_VER < MC_1_19_2
|
||||
import net.minecraft.world.level.levelgen.feature.StructureFeature;
|
||||
#endif
|
||||
import net.minecraft.world.level.levelgen.structure.StructureStart;
|
||||
import net.minecraft.world.level.levelgen.structure.pieces.StructurePieceSerializationContext;
|
||||
import net.minecraft.world.ticks.LevelChunkTicks;
|
||||
#endif
|
||||
#if POST_MC_1_18_2
|
||||
#if MC_VER >= MC_1_18_2
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.RegistryAccess;
|
||||
#if PRE_MC_1_19_2
|
||||
#if MC_VER < MC_1_19_2
|
||||
import net.minecraft.world.level.levelgen.feature.ConfiguredStructureFeature;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if MC_1_16_5 || MC_1_17_1
|
||||
#if MC_VER == MC_1_16_5 || MC_VER == MC_1_17_1
|
||||
import net.minecraft.world.level.material.Fluids;
|
||||
#endif
|
||||
|
||||
@@ -81,9 +81,11 @@ import net.minecraft.world.level.material.Fluid;
|
||||
|
||||
public class ChunkLoader
|
||||
{
|
||||
#if POST_MC_1_19_2
|
||||
private static boolean zeroChunkPosErrorLogged = false;
|
||||
|
||||
#if 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());
|
||||
#elif POST_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());
|
||||
#endif
|
||||
private static final String TAG_UPGRADE_DATA = "UpgradeData";
|
||||
@@ -93,7 +95,7 @@ public class ChunkLoader
|
||||
private static final String FLUID_TICKS_TAG_PRE18 = "LiquidTicks";
|
||||
private static final ConfigBasedLogger LOGGER = BatchGenerationEnvironment.LOAD_LOGGER;
|
||||
|
||||
#if POST_MC_1_18_2
|
||||
#if MC_VER >= MC_1_18_2
|
||||
private static BlendingData readBlendingData(CompoundTag chunkData)
|
||||
{
|
||||
BlendingData blendingData = null;
|
||||
@@ -109,16 +111,16 @@ public class ChunkLoader
|
||||
|
||||
private static LevelChunkSection[] readSections(LevelAccessor level, ChunkPos chunkPos, CompoundTag chunkData)
|
||||
{
|
||||
#if POST_MC_1_18_2
|
||||
#if PRE_MC_1_19_4
|
||||
#if MC_VER >= MC_1_18_2
|
||||
#if MC_VER < MC_1_19_4
|
||||
Registry<Biome> biomes = level.registryAccess().registryOrThrow(Registry.BIOME_REGISTRY);
|
||||
#else
|
||||
Registry<Biome> biomes = level.registryAccess().registryOrThrow(Registries.BIOME);
|
||||
#endif
|
||||
#if PRE_MC_1_18_2
|
||||
#if MC_VER < MC_1_18_2
|
||||
Codec<PalettedContainer<Biome>> biomeCodec = PalettedContainer.codec(
|
||||
biomes, biomes.byNameCodec(), PalettedContainer.Strategy.SECTION_BIOMES, biomes.getOrThrow(Biomes.PLAINS));
|
||||
#elif PRE_MC_1_19_2
|
||||
#elif MC_VER < MC_1_19_2
|
||||
Codec<PalettedContainer<Holder<Biome>>> biomeCodec = PalettedContainer.codec(
|
||||
biomes.asHolderIdMap(), biomes.holderByNameCodec(), PalettedContainer.Strategy.SECTION_BIOMES, biomes.getHolderOrThrow(Biomes.PLAINS));
|
||||
#else
|
||||
@@ -126,7 +128,7 @@ public class ChunkLoader
|
||||
biomes.asHolderIdMap(), biomes.holderByNameCodec(), PalettedContainer.Strategy.SECTION_BIOMES, biomes.getHolderOrThrow(Biomes.PLAINS));
|
||||
#endif
|
||||
#endif
|
||||
int i = #if PRE_MC_1_17_1 16; #else level.getSectionsCount(); #endif
|
||||
int i = #if MC_VER < MC_1_17_1 16; #else level.getSectionsCount(); #endif
|
||||
LevelChunkSection[] chunkSections = new LevelChunkSection[i];
|
||||
|
||||
boolean isLightOn = chunkData.getBoolean("isLightOn");
|
||||
@@ -139,7 +141,7 @@ public class ChunkLoader
|
||||
CompoundTag tagSection = tagSections.getCompound(j);
|
||||
int sectionYPos = tagSection.getByte("Y");
|
||||
|
||||
#if PRE_MC_1_18_2
|
||||
#if MC_VER < MC_1_18_2
|
||||
if (tagSection.contains("Palette", 9) && tagSection.contains("BlockStates", 12))
|
||||
{
|
||||
LevelChunkSection levelChunkSection = new LevelChunkSection(sectionYPos << 4);
|
||||
@@ -147,7 +149,7 @@ public class ChunkLoader
|
||||
tagSection.getLongArray("BlockStates"));
|
||||
levelChunkSection.recalcBlockCounts();
|
||||
if (!levelChunkSection.isEmpty())
|
||||
chunkSections[#if PRE_MC_1_17_1 sectionYPos #else level.getSectionIndexFromSectionY(sectionYPos) #endif ]
|
||||
chunkSections[#if MC_VER < MC_1_17_1 sectionYPos #else level.getSectionIndexFromSectionY(sectionYPos) #endif ]
|
||||
= levelChunkSection;
|
||||
}
|
||||
#else
|
||||
@@ -155,7 +157,7 @@ public class ChunkLoader
|
||||
if (sectionId >= 0 && sectionId < chunkSections.length)
|
||||
{
|
||||
PalettedContainer<BlockState> blockStateContainer;
|
||||
#if PRE_MC_1_18_2
|
||||
#if MC_VER < MC_1_18_2
|
||||
PalettedContainer<Biome> biomeContainer;
|
||||
#else
|
||||
PalettedContainer<Holder<Biome>> biomeContainer;
|
||||
@@ -165,7 +167,7 @@ public class ChunkLoader
|
||||
? BLOCK_STATE_CODEC.parse(NbtOps.INSTANCE, tagSection.getCompound("block_states")).promotePartial(string -> logErrors(chunkPos, sectionYPos, string)).getOrThrow(false, LOGGER::error)
|
||||
: new PalettedContainer<BlockState>(Block.BLOCK_STATE_REGISTRY, Blocks.AIR.defaultBlockState(), PalettedContainer.Strategy.SECTION_STATES);
|
||||
|
||||
#if PRE_MC_1_18_2
|
||||
#if MC_VER < MC_1_18_2
|
||||
biomeContainer = tagSection.contains("biomes", 10)
|
||||
? biomeCodec.parse(NbtOps.INSTANCE, tagSection.getCompound("biomes")).promotePartial(string -> logErrors(chunkPos, sectionYPos, string)).getOrThrow(false, LOGGER::error)
|
||||
: new PalettedContainer<Biome>(biomes, biomes.getOrThrow(Biomes.PLAINS), PalettedContainer.Strategy.SECTION_BIOMES);
|
||||
@@ -174,7 +176,7 @@ public class ChunkLoader
|
||||
? biomeCodec.parse(NbtOps.INSTANCE, tagSection.getCompound("biomes")).promotePartial(string -> logErrors(chunkPos, i, (String) string)).getOrThrow(false, LOGGER::error)
|
||||
: new PalettedContainer<Holder<Biome>>(biomes.asHolderIdMap(), biomes.getHolderOrThrow(Biomes.PLAINS), PalettedContainer.Strategy.SECTION_BIOMES);
|
||||
#endif
|
||||
#if PRE_MC_1_20_1
|
||||
#if MC_VER < MC_1_20_1
|
||||
chunkSections[sectionId] = new LevelChunkSection(sectionYPos, blockStateContainer, biomeContainer);
|
||||
#else
|
||||
chunkSections[sectionId] = new LevelChunkSection(blockStateContainer, biomeContainer);
|
||||
@@ -223,7 +225,7 @@ public class ChunkLoader
|
||||
|
||||
public static LevelChunk read(WorldGenLevel level, ChunkPos chunkPos, CompoundTag chunkData)
|
||||
{
|
||||
#if PRE_MC_1_18_2
|
||||
#if MC_VER < MC_1_18_2
|
||||
CompoundTag tagLevel = chunkData.getCompound("Level");
|
||||
#else
|
||||
CompoundTag tagLevel = chunkData;
|
||||
@@ -232,17 +234,41 @@ public class ChunkLoader
|
||||
ChunkPos actualPos = new ChunkPos(tagLevel.getInt("xPos"), tagLevel.getInt("zPos"));
|
||||
if (!Objects.equals(chunkPos, actualPos))
|
||||
{
|
||||
LOGGER.error("Chunk file at {} is in the wrong location; Ignoring. (Expected {}, got {})", chunkPos, chunkPos, actualPos);
|
||||
return null;
|
||||
#if MC_VER > MC_1_17_1
|
||||
if (actualPos.equals(ChunkPos.ZERO))
|
||||
#else
|
||||
if (actualPos.equals(ChunkPos.INVALID_CHUNK_POS))
|
||||
#endif
|
||||
{
|
||||
if (!zeroChunkPosErrorLogged)
|
||||
{
|
||||
zeroChunkPosErrorLogged = true;
|
||||
|
||||
// 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" +
|
||||
"This might happen if the world was created using an external program. \n" +
|
||||
"DH will attempt to parse the chunk anyway and won't log this message again.\n" +
|
||||
"If issues arise please try optimizing your world to fix this issue. \n" +
|
||||
"World optimization can be done from the singleplayer world selection screen."+
|
||||
"");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// everything is on one line to fix a JDK 17 compiler issue
|
||||
// if the issue is ever resolved, feel free to make this multi-line for readability
|
||||
LOGGER.error("Chunk file at ["+chunkPos.toString()+"] is in the wrong location. \nPlease try optimizing your world to fix this issue. \nWorld optimization can be done from the singleplayer world selection screen. \n(Expected pos: ["+chunkPos.toString()+"], actual ["+actualPos.toString()+"])");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
ChunkStatus.ChunkType chunkType = readChunkType(tagLevel);
|
||||
#if PRE_MC_1_18_2
|
||||
#if MC_VER < MC_1_18_2
|
||||
if (chunkType != ChunkStatus.ChunkType.LEVELCHUNK)
|
||||
return null;
|
||||
#else
|
||||
BlendingData blendingData = readBlendingData(tagLevel);
|
||||
#if PRE_MC_1_19_2
|
||||
#if MC_VER < MC_1_19_2
|
||||
if (chunkType == ChunkStatus.ChunkType.PROTOCHUNK && (blendingData == null || !blendingData.oldNoise()))
|
||||
return null;
|
||||
#else
|
||||
@@ -255,27 +281,27 @@ public class ChunkLoader
|
||||
|
||||
//================== Read params for making the LevelChunk ==================
|
||||
UpgradeData upgradeData = tagLevel.contains(TAG_UPGRADE_DATA, 10)
|
||||
? new UpgradeData(tagLevel.getCompound(TAG_UPGRADE_DATA)#if POST_MC_1_17_1 , level #endif )
|
||||
? new UpgradeData(tagLevel.getCompound(TAG_UPGRADE_DATA)#if MC_VER >= MC_1_17_1 , level #endif )
|
||||
: UpgradeData.EMPTY;
|
||||
|
||||
boolean isLightOn = tagLevel.getBoolean("isLightOn");
|
||||
#if PRE_MC_1_18_2
|
||||
#if MC_VER < MC_1_18_2
|
||||
ChunkBiomeContainer chunkBiomeContainer = new ChunkBiomeContainer(
|
||||
level.getLevel().registryAccess().registryOrThrow(Registry.BIOME_REGISTRY)#if POST_MC_1_17_1 , level #endif ,
|
||||
level.getLevel().registryAccess().registryOrThrow(Registry.BIOME_REGISTRY)#if MC_VER >= MC_1_17_1 , level #endif ,
|
||||
chunkPos, level.getLevel().getChunkSource().getGenerator().getBiomeSource(),
|
||||
tagLevel.contains("Biomes", 11) ? tagLevel.getIntArray("Biomes") : null);
|
||||
|
||||
TickList<Block> blockTicks = tagLevel.contains(BLOCK_TICKS_TAG_PRE18, 9)
|
||||
? ChunkTickList.create(tagLevel.getList(BLOCK_TICKS_TAG_PRE18, 10), Registry.BLOCK::getKey, Registry.BLOCK::get)
|
||||
: new ProtoTickList<Block>(block -> (block == null || block.defaultBlockState().isAir()), chunkPos,
|
||||
tagLevel.getList("ToBeTicked", 9)#if POST_MC_1_17_1 , level #endif );
|
||||
tagLevel.getList("ToBeTicked", 9)#if MC_VER >= MC_1_17_1 , level #endif );
|
||||
|
||||
TickList<Fluid> fluidTicks = tagLevel.contains(FLUID_TICKS_TAG_PRE18, 9)
|
||||
? ChunkTickList.create(tagLevel.getList(FLUID_TICKS_TAG_PRE18, 10), Registry.FLUID::getKey, Registry.FLUID::get)
|
||||
: new ProtoTickList<Fluid>(fluid -> (fluid == null || fluid == Fluids.EMPTY), chunkPos,
|
||||
tagLevel.getList("LiquidsToBeTicked", 9)#if POST_MC_1_17_1 , level #endif );
|
||||
tagLevel.getList("LiquidsToBeTicked", 9)#if MC_VER >= MC_1_17_1 , level #endif );
|
||||
#else
|
||||
#if PRE_MC_1_19_4
|
||||
#if MC_VER < MC_1_19_4
|
||||
LevelChunkTicks<Block> blockTicks = LevelChunkTicks.load(tagLevel.getList(BLOCK_TICKS_TAG_18, 10),
|
||||
string -> Registry.BLOCK.getOptional(ResourceLocation.tryParse(string)), chunkPos);
|
||||
LevelChunkTicks<Fluid> fluidTicks = LevelChunkTicks.load(tagLevel.getList(FLUID_TICKS_TAG_18, 10),
|
||||
@@ -291,7 +317,7 @@ public class ChunkLoader
|
||||
LevelChunkSection[] levelChunkSections = readSections(level, chunkPos, tagLevel);
|
||||
|
||||
// ====================== Make the chunk =========================
|
||||
#if PRE_MC_1_18_2
|
||||
#if MC_VER < MC_1_18_2
|
||||
LevelChunk chunk = new LevelChunk((Level) level.getLevel(), chunkPos, chunkBiomeContainer, upgradeData, blockTicks,
|
||||
fluidTicks, inhabitedTime, levelChunkSections, null);
|
||||
#else
|
||||
|
||||
+10
-10
@@ -41,7 +41,7 @@ import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.level.ChunkPos;
|
||||
import net.minecraft.world.level.ColorResolver;
|
||||
#if POST_MC_1_17_1
|
||||
#if MC_VER >= MC_1_17_1
|
||||
import net.minecraft.world.level.LevelHeightAccessor;
|
||||
#endif
|
||||
import net.minecraft.world.level.LightLayer;
|
||||
@@ -73,11 +73,11 @@ public class DhLitWorldGenRegion extends WorldGenRegion
|
||||
*/
|
||||
ReentrantLock getChunkLock = new ReentrantLock();
|
||||
|
||||
#if PRE_MC_1_18_2
|
||||
#if MC_VER < MC_1_18_2
|
||||
private ChunkPos overrideCenterPos = null;
|
||||
|
||||
public void setOverrideCenter(ChunkPos pos) { overrideCenterPos = pos; }
|
||||
#if PRE_MC_1_17_1
|
||||
#if MC_VER < MC_1_17_1
|
||||
@Override
|
||||
public int getCenterX()
|
||||
{
|
||||
@@ -104,7 +104,7 @@ public class DhLitWorldGenRegion extends WorldGenRegion
|
||||
List<ChunkAccess> chunkList, ChunkStatus chunkStatus, int writeRadius,
|
||||
BatchGenerationEnvironment.EmptyChunkGenerator generator)
|
||||
{
|
||||
super(serverLevel, chunkList #if POST_MC_1_17_1 , chunkStatus, writeRadius #endif );
|
||||
super(serverLevel, chunkList #if MC_VER >= MC_1_17_1 , chunkStatus, writeRadius #endif );
|
||||
this.firstPos = chunkList.get(0).getPos();
|
||||
this.generator = generator;
|
||||
this.lightEngine = lightEngine;
|
||||
@@ -115,7 +115,7 @@ public class DhLitWorldGenRegion extends WorldGenRegion
|
||||
|
||||
|
||||
|
||||
#if POST_MC_1_17_1
|
||||
#if MC_VER >= MC_1_17_1
|
||||
// Bypass BCLib mixin overrides.
|
||||
@Override
|
||||
public boolean ensureCanWrite(BlockPos blockPos)
|
||||
@@ -130,7 +130,7 @@ public class DhLitWorldGenRegion extends WorldGenRegion
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#if POST_MC_1_18_2
|
||||
#if MC_VER >= MC_1_18_2
|
||||
if (center.isUpgrading())
|
||||
{
|
||||
LevelHeightAccessor levelHeightAccessor = center.getHeightAccessorForGeneration();
|
||||
@@ -185,7 +185,7 @@ public class DhLitWorldGenRegion extends WorldGenRegion
|
||||
BlockState blockState = this.getBlockState(blockPos);
|
||||
|
||||
// This is a bypass for the spawner block since MC complains about not having it
|
||||
#if POST_MC_1_17_1
|
||||
#if MC_VER >= MC_1_17_1
|
||||
if (blockState.getBlock() instanceof SpawnerBlock)
|
||||
{
|
||||
return ((EntityBlock) blockState.getBlock()).newBlockEntity(blockPos, blockState);
|
||||
@@ -269,7 +269,7 @@ public class DhLitWorldGenRegion extends WorldGenRegion
|
||||
ChunkAccess chunk = getChunkAccess(i, j, chunkStatus, bl);
|
||||
if (chunk instanceof LevelChunk)
|
||||
{
|
||||
chunk = new ImposterProtoChunk((LevelChunk) chunk #if POST_MC_1_18_2 , true #endif );
|
||||
chunk = new ImposterProtoChunk((LevelChunk) chunk #if MC_VER >= MC_1_18_2 , true #endif );
|
||||
}
|
||||
return chunk;
|
||||
}
|
||||
@@ -331,7 +331,7 @@ public class DhLitWorldGenRegion extends WorldGenRegion
|
||||
|
||||
private Biome _getBiome(BlockPos pos)
|
||||
{
|
||||
#if POST_MC_1_18_2
|
||||
#if MC_VER >= MC_1_18_2
|
||||
return getBiome(pos).value();
|
||||
#else
|
||||
return getBiome(pos);
|
||||
@@ -340,7 +340,7 @@ public class DhLitWorldGenRegion extends WorldGenRegion
|
||||
|
||||
public int calculateBlockTint(BlockPos blockPos, ColorResolver colorResolver)
|
||||
{
|
||||
#if PRE_MC_1_19_2
|
||||
#if MC_VER < MC_1_19_2
|
||||
int i = (Minecraft.getInstance()).options.biomeBlendRadius;
|
||||
#else
|
||||
int i = (Minecraft.getInstance()).options.biomeBlendRadius().get();
|
||||
|
||||
+3
-3
@@ -39,7 +39,7 @@ public class DummyLightEngine extends LevelLightEngine
|
||||
}
|
||||
|
||||
|
||||
#if PRE_MC_1_20_1
|
||||
#if MC_VER < MC_1_20_1
|
||||
@Override
|
||||
public void onBlockEmissionIncrease(BlockPos blockPos, int i) { }
|
||||
|
||||
@@ -63,7 +63,7 @@ public class DummyLightEngine extends LevelLightEngine
|
||||
#endif
|
||||
|
||||
@Override
|
||||
public void queueSectionData(LightLayer lightLayer, SectionPos sectionPos, @Nullable DataLayer dataLayer #if PRE_MC_1_20_1 , boolean bl #endif ) { }
|
||||
public void queueSectionData(LightLayer lightLayer, SectionPos sectionPos, @Nullable DataLayer dataLayer #if MC_VER < MC_1_20_1 , boolean bl #endif ) { }
|
||||
|
||||
@Override
|
||||
public void checkBlock(BlockPos blockPos) { }
|
||||
@@ -87,7 +87,7 @@ public class DummyLightEngine extends LevelLightEngine
|
||||
@Override
|
||||
public void retainData(ChunkPos chunkPos, boolean bl) { }
|
||||
|
||||
#if POST_MC_1_17_1
|
||||
#if MC_VER >= MC_1_17_1
|
||||
@Override
|
||||
public int getLightSectionCount() { throw new UnsupportedOperationException("This should never be used!"); }
|
||||
@Override
|
||||
|
||||
+4
-4
@@ -23,12 +23,12 @@ import com.seibel.distanthorizons.core.dependencyInjection.ModAccessorInjector;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IStarlightAccessor;
|
||||
|
||||
import net.minecraft.world.level.BlockGetter;
|
||||
#if POST_MC_1_17_1
|
||||
#if MC_VER >= MC_1_17_1
|
||||
import net.minecraft.world.level.LevelHeightAccessor;
|
||||
#endif
|
||||
import net.minecraft.world.level.chunk.ChunkStatus;
|
||||
import net.minecraft.world.level.chunk.LightChunkGetter;
|
||||
#if POST_MC_1_20_1
|
||||
#if MC_VER >= MC_1_20_1
|
||||
import net.minecraft.world.level.chunk.LightChunk;
|
||||
#endif
|
||||
|
||||
@@ -50,7 +50,7 @@ public class LightGetterAdaptor implements LightChunkGetter
|
||||
}
|
||||
|
||||
@Override
|
||||
public #if PRE_MC_1_20_1 BlockGetter #else LightChunk #endif getChunkForLighting(int chunkX, int chunkZ)
|
||||
public #if MC_VER < MC_1_20_1 BlockGetter #else LightChunk #endif getChunkForLighting(int chunkX, int chunkZ)
|
||||
{
|
||||
if (genRegion == null)
|
||||
throw new IllegalStateException("World Gen region has not been set!");
|
||||
@@ -64,7 +64,7 @@ public class LightGetterAdaptor implements LightChunkGetter
|
||||
return shouldReturnNull ? null : (genRegion != null ? genRegion : heightGetter);
|
||||
}
|
||||
|
||||
#if POST_MC_1_17_1
|
||||
#if MC_VER >= MC_1_17_1
|
||||
public LevelHeightAccessor getLevelHeightAccessor()
|
||||
{
|
||||
return heightGetter;
|
||||
|
||||
+45
-5
@@ -1,13 +1,15 @@
|
||||
package com.seibel.distanthorizons.common.wrappers.worldGeneration.mimicObject;
|
||||
|
||||
import com.seibel.distanthorizons.common.wrappers.worldGeneration.BatchGenerationEnvironment;
|
||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.NbtIo;
|
||||
import net.minecraft.world.level.ChunkPos;
|
||||
import net.minecraft.world.level.chunk.storage.RegionFile;
|
||||
import net.minecraft.world.level.chunk.storage.RegionFileStorage;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
@@ -15,11 +17,23 @@ import java.nio.file.Path;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
/**
|
||||
* @deprecated should be replaced with net.minecraft.world.level.chunk.storage.IOWorker to
|
||||
* prevent potential file corruption and issues with the C2ME mod.
|
||||
* Generally this would be done via (MC ServerLevel) level.getChunkSource().chunkMap.worker#loadAsync()
|
||||
*/
|
||||
@Deprecated
|
||||
public class RegionFileStorageExternalCache implements AutoCloseable
|
||||
{
|
||||
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
|
||||
|
||||
/** Can be null due to the C2ME mod */
|
||||
@Nullable
|
||||
public final RegionFileStorage storage;
|
||||
public static final int MAX_CACHE_SIZE = 16;
|
||||
|
||||
public static boolean regionCacheNullPointerWarningSent = false;
|
||||
|
||||
/**
|
||||
* Present to reduce the chance that we accidentally break underlying MC code that isn't thread safe,
|
||||
* specifically: "it.unimi.dsi.fastutil.longs.Long2ObjectLinkedOpenHashMap.getAndMoveToFirst()"
|
||||
@@ -50,6 +64,19 @@ public class RegionFileStorageExternalCache implements AutoCloseable
|
||||
@Nullable
|
||||
public RegionFile getRegionFile(ChunkPos pos) throws IOException
|
||||
{
|
||||
if (this.storage == null)
|
||||
{
|
||||
if (!regionCacheNullPointerWarningSent)
|
||||
{
|
||||
regionCacheNullPointerWarningSent = true;
|
||||
LOGGER.warn("Unable to access Minecraft's chunk cache. This may be due to another mod changing said cache. DH will be unable to access any Minecraft chunk data until said mod is removed.");
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
long posLong = ChunkPos.asLong(pos.getRegionX(), pos.getRegionZ());
|
||||
RegionFile rFile = null;
|
||||
|
||||
@@ -64,7 +91,7 @@ public class RegionFileStorageExternalCache implements AutoCloseable
|
||||
{
|
||||
this.getRegionFileLock.lock();
|
||||
|
||||
#if MC_1_16_5 || MC_1_17_1
|
||||
#if MC_VER == MC_1_16_5 || MC_VER == MC_1_17_1
|
||||
rFile = this.storage.getRegionFile(pos);
|
||||
|
||||
// keeping the region cache size low helps prevent concurrency issues
|
||||
@@ -84,7 +111,7 @@ public class RegionFileStorageExternalCache implements AutoCloseable
|
||||
}
|
||||
catch (ArrayIndexOutOfBoundsException e)
|
||||
{
|
||||
#if MC_1_16_5 || MC_1_17_1
|
||||
#if MC_VER == MC_1_16_5 || MC_VER == MC_1_17_1
|
||||
// the file just wasn't cached
|
||||
break;
|
||||
#else
|
||||
@@ -98,6 +125,19 @@ public class RegionFileStorageExternalCache implements AutoCloseable
|
||||
}
|
||||
#endif
|
||||
}
|
||||
catch (NullPointerException e)
|
||||
{
|
||||
// Can sometimes happen when other mods modify the region cache system (IE C2ME)
|
||||
// instead of blowing up, just use DH's cache instead
|
||||
|
||||
if (!regionCacheNullPointerWarningSent)
|
||||
{
|
||||
regionCacheNullPointerWarningSent = true;
|
||||
LOGGER.warn("Unable to access Minecraft's chunk cache. This may be due to another mod changing said cache. Falling back to DH's internal cache.");
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
finally
|
||||
{
|
||||
this.getRegionFileLock.unlock();
|
||||
@@ -126,7 +166,7 @@ public class RegionFileStorageExternalCache implements AutoCloseable
|
||||
|
||||
// Otherwise, check if file exist, and if so, add it to the cache
|
||||
Path storageFolderPath;
|
||||
#if MC_1_16_5 || MC_1_17_1
|
||||
#if MC_VER == MC_1_16_5 || MC_VER == MC_1_17_1
|
||||
storageFolderPath = this.storage.folder.toPath();
|
||||
#else
|
||||
storageFolderPath = this.storage.folder;
|
||||
@@ -138,7 +178,7 @@ public class RegionFileStorageExternalCache implements AutoCloseable
|
||||
}
|
||||
|
||||
Path regionFilePath = storageFolderPath.resolve("r." + pos.getRegionX() + "." + pos.getRegionZ() + ".mca");
|
||||
#if MC_1_16_5 || MC_1_17_1
|
||||
#if MC_VER == MC_1_16_5 || MC_VER == MC_1_17_1
|
||||
rFile = new RegionFile(regionFilePath.toFile(), storageFolderPath.toFile(), false);
|
||||
#else
|
||||
rFile = new RegionFile(regionFilePath, storageFolderPath, false);
|
||||
|
||||
+15
-15
@@ -37,49 +37,49 @@ import net.minecraft.world.level.WorldGenLevel;
|
||||
import net.minecraft.world.level.chunk.ChunkAccess;
|
||||
import net.minecraft.world.level.chunk.ChunkStatus;
|
||||
import net.minecraft.world.level.levelgen.WorldGenSettings;
|
||||
#if PRE_MC_1_19_2
|
||||
#if MC_VER < MC_1_19_2
|
||||
import net.minecraft.world.level.levelgen.feature.ConfiguredStructureFeature;
|
||||
import net.minecraft.world.level.StructureFeatureManager;
|
||||
#else
|
||||
#if POST_MC_1_19_4
|
||||
#if MC_VER >= MC_1_19_4
|
||||
import net.minecraft.world.level.levelgen.WorldOptions;
|
||||
#endif
|
||||
import net.minecraft.world.level.levelgen.structure.Structure;
|
||||
import net.minecraft.world.level.StructureManager;
|
||||
#endif
|
||||
#if POST_MC_1_18_2
|
||||
#if MC_VER >= MC_1_18_2
|
||||
import net.minecraft.world.level.levelgen.structure.StructureCheck;
|
||||
#endif
|
||||
|
||||
import net.minecraft.world.level.levelgen.structure.StructureStart;
|
||||
|
||||
#if PRE_MC_1_18_2
|
||||
#if MC_VER < MC_1_18_2
|
||||
import net.minecraft.world.level.levelgen.feature.StructureFeature;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
public class WorldGenStructFeatManager extends #if PRE_MC_1_19_2 StructureFeatureManager #else StructureManager #endif
|
||||
public class WorldGenStructFeatManager extends #if MC_VER < MC_1_19_2 StructureFeatureManager #else StructureManager #endif
|
||||
{
|
||||
final WorldGenLevel genLevel;
|
||||
|
||||
#if PRE_MC_1_19_4
|
||||
#if MC_VER < MC_1_19_4
|
||||
WorldGenSettings worldGenSettings;
|
||||
#else
|
||||
WorldOptions worldOptions;
|
||||
#endif
|
||||
|
||||
#if POST_MC_1_18_2
|
||||
#if MC_VER >= MC_1_18_2
|
||||
StructureCheck structureCheck;
|
||||
#endif
|
||||
|
||||
#if PRE_MC_1_19_4
|
||||
#if MC_VER < MC_1_19_4
|
||||
public WorldGenStructFeatManager(
|
||||
WorldGenSettings worldGenSettings,
|
||||
WorldGenLevel genLevel #if POST_MC_1_18_2 , StructureCheck structureCheck #endif )
|
||||
WorldGenLevel genLevel #if MC_VER >= MC_1_18_2 , StructureCheck structureCheck #endif )
|
||||
{
|
||||
|
||||
super(genLevel, worldGenSettings #if POST_MC_1_18_2 , structureCheck #endif );
|
||||
super(genLevel, worldGenSettings #if MC_VER >= MC_1_18_2 , structureCheck #endif );
|
||||
this.genLevel = genLevel;
|
||||
this.worldGenSettings = worldGenSettings;
|
||||
}
|
||||
@@ -100,8 +100,8 @@ public class WorldGenStructFeatManager extends #if PRE_MC_1_19_2 StructureFeatur
|
||||
{
|
||||
if (worldGenRegion == genLevel)
|
||||
return this;
|
||||
#if PRE_MC_1_19_4
|
||||
return new WorldGenStructFeatManager(worldGenSettings, worldGenRegion #if POST_MC_1_18_2 , structureCheck #endif );
|
||||
#if MC_VER < MC_1_19_4
|
||||
return new WorldGenStructFeatManager(worldGenSettings, worldGenRegion #if MC_VER >= MC_1_18_2 , structureCheck #endif );
|
||||
#else
|
||||
return new WorldGenStructFeatManager(worldOptions, worldGenRegion, structureCheck);
|
||||
#endif
|
||||
@@ -113,7 +113,7 @@ public class WorldGenStructFeatManager extends #if PRE_MC_1_19_2 StructureFeatur
|
||||
return genLevel.getChunk(x, z, status, false);
|
||||
}
|
||||
|
||||
#if PRE_MC_1_18_2
|
||||
#if MC_VER < MC_1_18_2
|
||||
@Override
|
||||
public Stream<? extends StructureStart<?>> startsForFeature(
|
||||
SectionPos sectionPos2,
|
||||
@@ -140,7 +140,7 @@ public class WorldGenStructFeatManager extends #if PRE_MC_1_19_2 StructureFeatur
|
||||
return chunk.hasAnyStructureReferences();
|
||||
}
|
||||
|
||||
#if MC_1_18_1
|
||||
#if MC_VER == MC_1_18_1
|
||||
@Override
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
public List<? extends StructureStart<?>> startsForFeature(SectionPos sectionPos,
|
||||
@@ -165,7 +165,7 @@ public class WorldGenStructFeatManager extends #if PRE_MC_1_19_2 StructureFeatur
|
||||
return builder.build();
|
||||
}
|
||||
#else
|
||||
#if PRE_MC_1_19_2
|
||||
#if MC_VER < MC_1_19_2
|
||||
@Override
|
||||
public List<StructureStart> startsForFeature(SectionPos sectionPos, Predicate<ConfiguredStructureFeature<?, ?>> predicate)
|
||||
{
|
||||
|
||||
+5
-5
@@ -27,12 +27,12 @@ import com.seibel.distanthorizons.common.wrappers.worldGeneration.BatchGeneratio
|
||||
import com.seibel.distanthorizons.common.wrappers.worldGeneration.ThreadedParameters;
|
||||
|
||||
import net.minecraft.server.level.WorldGenRegion;
|
||||
#if PRE_MC_1_19_2
|
||||
#if MC_VER < MC_1_19_2
|
||||
#endif
|
||||
import net.minecraft.world.level.chunk.ChunkAccess;
|
||||
import net.minecraft.world.level.chunk.ChunkStatus;
|
||||
import net.minecraft.world.level.chunk.ProtoChunk;
|
||||
#if POST_MC_1_18_2
|
||||
#if MC_VER >= MC_1_18_2
|
||||
import net.minecraft.world.level.levelgen.blending.Blender;
|
||||
#endif
|
||||
|
||||
@@ -65,12 +65,12 @@ public final class StepBiomes
|
||||
for (ChunkAccess chunk : chunksToDo)
|
||||
{
|
||||
// System.out.println("StepBiomes: "+chunk.getPos());
|
||||
#if PRE_MC_1_18_2
|
||||
#if MC_VER < MC_1_18_2
|
||||
environment.params.generator.createBiomes(environment.params.biomes, chunk);
|
||||
#elif PRE_MC_1_19_2
|
||||
#elif MC_VER < MC_1_19_2
|
||||
chunk = environment.joinSync(environment.params.generator.createBiomes(environment.params.biomes, Runnable::run, Blender.of(worldGenRegion),
|
||||
tParams.structFeat.forWorldGenRegion(worldGenRegion), chunk));
|
||||
#elif PRE_MC_1_19_4
|
||||
#elif MC_VER < MC_1_19_4
|
||||
chunk = environment.joinSync(environment.params.generator.createBiomes(environment.params.biomes, Runnable::run, environment.params.randomState, Blender.of(worldGenRegion),
|
||||
tParams.structFeat.forWorldGenRegion(worldGenRegion), chunk));
|
||||
#else
|
||||
|
||||
+28
-20
@@ -19,24 +19,24 @@
|
||||
|
||||
package com.seibel.distanthorizons.common.wrappers.worldGeneration.step;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import com.seibel.distanthorizons.common.wrappers.chunk.ChunkWrapper;
|
||||
import com.seibel.distanthorizons.common.wrappers.worldGeneration.BatchGenerationEnvironment;
|
||||
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.util.gridList.ArrayGridList;
|
||||
|
||||
import net.minecraft.ReportedException;
|
||||
import net.minecraft.world.level.chunk.ChunkAccess;
|
||||
import net.minecraft.world.level.chunk.ChunkStatus;
|
||||
import net.minecraft.world.level.chunk.ProtoChunk;
|
||||
import net.minecraft.world.level.levelgen.Heightmap;
|
||||
#if POST_MC_1_18_2
|
||||
#endif
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
|
||||
public final class StepFeatures
|
||||
{
|
||||
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
|
||||
|
||||
public static final ChunkStatus STATUS = ChunkStatus.FEATURES;
|
||||
|
||||
private final BatchGenerationEnvironment environment;
|
||||
@@ -51,36 +51,44 @@ public final class StepFeatures
|
||||
ThreadedParameters tParams, DhLitWorldGenRegion worldGenRegion,
|
||||
ArrayGridList<ChunkWrapper> chunkWrappers)
|
||||
{
|
||||
ArrayList<ChunkAccess> chunksToDo = new ArrayList<ChunkAccess>();
|
||||
|
||||
for (ChunkWrapper chunkWrapper : chunkWrappers)
|
||||
{
|
||||
ChunkAccess chunk = chunkWrapper.getChunk();
|
||||
if (chunk.getStatus().isOrAfter(STATUS)) continue;
|
||||
((ProtoChunk) chunk).setStatus(STATUS);
|
||||
chunksToDo.add(chunk);
|
||||
}
|
||||
|
||||
for (ChunkAccess chunk : chunksToDo)
|
||||
{
|
||||
if (chunk.getStatus().isOrAfter(STATUS))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (chunk instanceof ProtoChunk)
|
||||
{
|
||||
((ProtoChunk) chunk).setStatus(STATUS);
|
||||
}
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
#if PRE_MC_1_18_2
|
||||
#if MC_VER < MC_1_18_2
|
||||
worldGenRegion.setOverrideCenter(chunk.getPos());
|
||||
environment.params.generator.applyBiomeDecoration(worldGenRegion, tParams.structFeat);
|
||||
#else
|
||||
environment.params.generator.applyBiomeDecoration(worldGenRegion, chunk,
|
||||
tParams.structFeat.forWorldGenRegion(worldGenRegion));
|
||||
if (worldGenRegion.hasChunk(chunkWrapper.getChunkPos().x, chunkWrapper.getChunkPos().z))
|
||||
{
|
||||
this.environment.params.generator.applyBiomeDecoration(worldGenRegion, chunk, tParams.structFeat.forWorldGenRegion(worldGenRegion));
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGGER.warn("Unable to generate features for chunk at pos ["+chunkWrapper.getChunkPos()+"], world gen region doesn't contain the chunk.");
|
||||
}
|
||||
#endif
|
||||
|
||||
Heightmap.primeHeightmaps(chunk, STATUS.heightmapsAfter());
|
||||
BatchGenerationEnvironment.clearDistantGenerationMixinData();
|
||||
}
|
||||
catch (ReportedException e)
|
||||
catch (Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
LOGGER.warn("Unexpected issue when generating features for chunk at pos ["+chunkWrapper.getChunkPos()+"], error: ["+e.getMessage()+"].", e);
|
||||
// FIXME: Features concurrent modification issue. Something about cocobeans might just
|
||||
// error out. For now just retry.
|
||||
// error out. For now just retry.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+6
-6
@@ -28,14 +28,14 @@ import com.seibel.distanthorizons.common.wrappers.worldGeneration.ThreadedParame
|
||||
|
||||
import com.seibel.distanthorizons.core.util.objects.UncheckedInterruptedException;
|
||||
import net.minecraft.server.level.WorldGenRegion;
|
||||
#if POST_MC_1_17_1
|
||||
#if MC_VER >= MC_1_17_1
|
||||
#endif
|
||||
#if PRE_MC_1_19_2
|
||||
#if MC_VER < MC_1_19_2
|
||||
#endif
|
||||
import net.minecraft.world.level.chunk.ChunkAccess;
|
||||
import net.minecraft.world.level.chunk.ChunkStatus;
|
||||
import net.minecraft.world.level.chunk.ProtoChunk;
|
||||
#if POST_MC_1_18_2
|
||||
#if MC_VER >= MC_1_18_2
|
||||
import net.minecraft.world.level.levelgen.blending.Blender;
|
||||
#endif
|
||||
|
||||
@@ -69,12 +69,12 @@ public final class StepNoise
|
||||
for (ChunkAccess chunk : chunksToDo)
|
||||
{
|
||||
// System.out.println("StepNoise: "+chunk.getPos());
|
||||
#if PRE_MC_1_17_1
|
||||
#if MC_VER < MC_1_17_1
|
||||
environment.params.generator.fillFromNoise(worldGenRegion, tParams.structFeat, chunk);
|
||||
#elif PRE_MC_1_18_2
|
||||
#elif MC_VER < MC_1_18_2
|
||||
chunk = environment.joinSync(environment.params.generator.fillFromNoise(Runnable::run,
|
||||
tParams.structFeat.forWorldGenRegion(worldGenRegion), chunk));
|
||||
#elif PRE_MC_1_19_2
|
||||
#elif MC_VER < MC_1_19_2
|
||||
chunk = environment.joinSync(environment.params.generator.fillFromNoise(Runnable::run, Blender.of(worldGenRegion),
|
||||
tParams.structFeat.forWorldGenRegion(worldGenRegion), chunk));
|
||||
#else
|
||||
|
||||
+1
-1
@@ -27,7 +27,7 @@ import com.seibel.distanthorizons.common.wrappers.worldGeneration.BatchGeneratio
|
||||
import com.seibel.distanthorizons.common.wrappers.worldGeneration.ThreadedParameters;
|
||||
|
||||
import net.minecraft.server.level.WorldGenRegion;
|
||||
#if PRE_MC_1_19_2
|
||||
#if MC_VER < MC_1_19_2
|
||||
#endif
|
||||
import net.minecraft.world.level.chunk.ChunkAccess;
|
||||
import net.minecraft.world.level.chunk.ChunkStatus;
|
||||
|
||||
+5
-5
@@ -77,10 +77,10 @@ public final class StepStructureStart
|
||||
}
|
||||
}
|
||||
|
||||
#if PRE_MC_1_19_2
|
||||
#if MC_VER < MC_1_19_2
|
||||
if (environment.params.worldGenSettings.generateFeatures())
|
||||
{
|
||||
#elif PRE_MC_1_19_4
|
||||
#elif MC_VER < MC_1_19_4
|
||||
if (environment.params.worldGenSettings.generateStructures()) {
|
||||
#else
|
||||
if (environment.params.worldOptions.generateStructures())
|
||||
@@ -98,10 +98,10 @@ public final class StepStructureStart
|
||||
// and should prevent some concurrency issues
|
||||
STRUCTURE_PLACEMENT_LOCK.lock();
|
||||
|
||||
#if PRE_MC_1_19_2
|
||||
#if MC_VER < MC_1_19_2
|
||||
environment.params.generator.createStructures(environment.params.registry, tParams.structFeat, chunk, environment.params.structures,
|
||||
environment.params.worldSeed);
|
||||
#elif PRE_MC_1_19_4
|
||||
#elif MC_VER < MC_1_19_4
|
||||
environment.params.generator.createStructures(environment.params.registry, environment.params.randomState, tParams.structFeat, chunk, environment.params.structures,
|
||||
environment.params.worldSeed);
|
||||
#else
|
||||
@@ -110,7 +110,7 @@ public final class StepStructureStart
|
||||
tParams.structFeat, chunk, environment.params.structures);
|
||||
#endif
|
||||
|
||||
#if POST_MC_1_18_2
|
||||
#if MC_VER >= MC_1_18_2
|
||||
try
|
||||
{
|
||||
tParams.structCheck.onStructureLoad(chunk.getPos(), chunk.getAllStarts());
|
||||
|
||||
+2
-2
@@ -61,9 +61,9 @@ public final class StepSurface
|
||||
for (ChunkAccess chunk : chunksToDo)
|
||||
{
|
||||
// System.out.println("StepSurface: "+chunk.getPos());
|
||||
#if PRE_MC_1_18_2
|
||||
#if MC_VER < MC_1_18_2
|
||||
environment.params.generator.buildSurfaceAndBedrock(worldGenRegion, chunk);
|
||||
#elif PRE_MC_1_19_2
|
||||
#elif MC_VER < MC_1_19_2
|
||||
environment.params.generator.buildSurface(worldGenRegion, tParams.structFeat.forWorldGenRegion(worldGenRegion), chunk);
|
||||
#else
|
||||
environment.params.generator.buildSurface(worldGenRegion, tParams.structFeat.forWorldGenRegion(worldGenRegion), environment.params.randomState, chunk);
|
||||
|
||||
+3
-3
@@ -14,7 +14,7 @@ By sending a merge request, you agree to abide by the Distant Horizons [Contribu
|
||||
Contributions to this project are under the [lesser GPL v3 license](LICENSE.txt) Copyright James Seibel, so please include the [license header](license_header.txt) at the top of any new code files.
|
||||
|
||||
1. Fork, then clone the repo: \
|
||||
`git clone --recurse-submodules https://gitlab.com/jeseibel/minecraft-lod-mod.git`
|
||||
`git clone --recurse-submodules https://gitlab.com/jeseibel/distant-horizons.git`
|
||||
|
||||
2. Set up your dev environment: \
|
||||
`./gradlew build`
|
||||
@@ -37,13 +37,13 @@ Contributions to this project are under the [lesser GPL v3 license](LICENSE.txt)
|
||||
`./gradlew fabric:runClient` \
|
||||
When running the game, load or generate a world to confirm Distant Horizons initializes correctly.
|
||||
|
||||
9. Push to your fork, make sure to include the Core submodule, and submit a [new merge request](https://gitlab.com/jeseibel/minecraft-lod-mod/-/merge_requests/new).
|
||||
9. Push to your fork, make sure to include the Core submodule, and submit a [new merge request](https://gitlab.com/jeseibel/distant-horizons/-/merge_requests/new).
|
||||
|
||||
|
||||
|
||||
## General Guidelines
|
||||
|
||||
* Check the existing issue list to verify that a given [bug](https://gitlab.com/jeseibel/minecraft-lod-mod/-/issues/?sort=created_date&state=opened&label_name%5B%5D=Bug&first_page_size=100), [feature](https://gitlab.com/jeseibel/minecraft-lod-mod/-/issues/?sort=created_date&state=opened&label_name%5B%5D=Feature&first_page_size=100), or [improvement](https://gitlab.com/jeseibel/minecraft-lod-mod/-/issues/?sort=created_date&state=opened&label_name%5B%5D=Improvement&first_page_size=100) hasn't already been submitted.
|
||||
* Check the existing issue list to verify that a given [bug](https://gitlab.com/jeseibel/distant-horizons/-/issues/?sort=created_date&state=opened&label_name%5B%5D=Bug&first_page_size=100), [feature](https://gitlab.com/jeseibel/distant-horizons/-/issues/?sort=created_date&state=opened&label_name%5B%5D=Feature&first_page_size=100), or [improvement](https://gitlab.com/jeseibel/distant-horizons/-/issues/?sort=created_date&state=opened&label_name%5B%5D=Improvement&first_page_size=100) hasn't already been submitted.
|
||||
* Please open an issue if things aren't working as expected.
|
||||
* Open a merge request to: fix bugs, fix documentations, improve an existing system, or complete a feature.
|
||||
* When contributing:
|
||||
|
||||
+1
-1
Submodule coreSubProjects updated: 773f17ddfe...87e5647379
+40
-48
@@ -1,65 +1,49 @@
|
||||
plugins {
|
||||
id "fabric-loom" version "1.1.+"
|
||||
}
|
||||
unimined.minecraft {
|
||||
fabric {
|
||||
loader rootProject.fabric_loader_version
|
||||
accessWidener(project(":common").file("src/main/resources/${accessWidenerVersion}.distanthorizons.accesswidener"))
|
||||
|
||||
loom {
|
||||
accessWidenerPath = project(":common").file("src/main/resources/${accessWidenerVersion}.distanthorizons.accesswidener")
|
||||
|
||||
// "runs" isn't required, but when we do need it then it can be useful
|
||||
runs {
|
||||
client {
|
||||
client()
|
||||
setConfigName("Fabric Client")
|
||||
ideConfigGenerated(true)
|
||||
runDir("../run")
|
||||
}
|
||||
server {
|
||||
server()
|
||||
setConfigName("Fabric Server")
|
||||
ideConfigGenerated(true)
|
||||
runDir("../run")
|
||||
}
|
||||
skipInsertAw = true
|
||||
}
|
||||
}
|
||||
|
||||
remapJar {
|
||||
inputFile = shadowJar.archiveFile
|
||||
dependsOn shadowJar
|
||||
classifier null
|
||||
}
|
||||
|
||||
configurations {
|
||||
// The addModJar basically embeds the mod to the built jar
|
||||
addModJar
|
||||
include.extendsFrom addModJar
|
||||
modImplementation.extendsFrom addModJar
|
||||
dummy
|
||||
}
|
||||
|
||||
def addMod(path, enabled) {
|
||||
if (enabled == "2")
|
||||
dependencies { modImplementation(path) }
|
||||
else if (enabled == "1")
|
||||
dependencies { modCompileOnly(path) }
|
||||
dependencies { compileOnly(path) }
|
||||
}
|
||||
|
||||
// TODO: There currently seems to be a bug which causes the regular addModJar to not work, swap back to the regular addModJar when fixed
|
||||
def addModJar_(path) {
|
||||
dependencies {
|
||||
modImplementation(path)
|
||||
include(path)
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
minecraft "com.mojang:minecraft:${minecraft_version}"
|
||||
mappings loom.layered() {
|
||||
// Mojmap mappings
|
||||
officialMojangMappings()
|
||||
// Parchment mappings (it adds parameter mappings & javadoc)
|
||||
parchment("org.parchmentmc.data:parchment-${rootProject.parchment_version}@zip")
|
||||
}
|
||||
// Fabric loader
|
||||
modImplementation "net.fabricmc:fabric-loader:${rootProject.fabric_loader_version}"
|
||||
|
||||
annotationProcessor "javax.annotation:javax.annotation-api:1.3.2"
|
||||
implementation("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"
|
||||
modImplementation "javax.annotation:javax.annotation-api:1.3.2"
|
||||
|
||||
// Fabric API
|
||||
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-resource-loader-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-networking-api-v1", rootProject.fabric_api_version))
|
||||
addModJar_(fabricApi.fabricModule("fabric-api-base", rootProject.fabric_api_version))
|
||||
addModJar_(fabricApi.fabricModule("fabric-lifecycle-events-v1", rootProject.fabric_api_version))
|
||||
addModJar_(fabricApi.fabricModule("fabric-resource-loader-v0", rootProject.fabric_api_version))
|
||||
addModJar_(fabricApi.fabricModule("fabric-events-interaction-v0", rootProject.fabric_api_version))
|
||||
addModJar_(fabricApi.fabricModule("fabric-rendering-v1", rootProject.fabric_api_version)) // TODO: Remove this as it is only needed in 1 line (FabricClientProxy)
|
||||
addModJar_(fabricApi.fabricModule("fabric-networking-api-v1", rootProject.fabric_api_version))
|
||||
|
||||
// Mod Menu
|
||||
modImplementation("com.terraformersmc:modmenu:${rootProject.modmenu_version}")
|
||||
@@ -114,6 +98,12 @@ dependencies {
|
||||
}
|
||||
}
|
||||
|
||||
remapJar {
|
||||
inputFile = shadowJar.archiveFile
|
||||
dependsOn shadowJar
|
||||
// classifier null
|
||||
}
|
||||
|
||||
|
||||
task deleteResources(type: Delete) {
|
||||
delete file("build/resources/main")
|
||||
@@ -124,11 +114,13 @@ processResources {
|
||||
dependsOn(copyCommonLoaderResources)
|
||||
}
|
||||
|
||||
runClient {
|
||||
dependsOn(copyCoreResources)
|
||||
dependsOn(copyCommonLoaderResources)
|
||||
jvmArgs([ "-XX:-OmitStackTraceInFastThrow", minecraftMemoryJavaArg ])
|
||||
finalizedBy(deleteResources)
|
||||
afterEvaluate {
|
||||
runClient {
|
||||
dependsOn(copyCoreResources)
|
||||
dependsOn(copyCommonLoaderResources)
|
||||
// jvmArgs([ "-XX:-OmitStackTraceInFastThrow", minecraftMemoryJavaArg ])
|
||||
finalizedBy(deleteResources)
|
||||
}
|
||||
}
|
||||
|
||||
//jar {
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
package com.seibel.distanthorizons.fabric;
|
||||
|
||||
import com.seibel.distanthorizons.common.LodCommonMain;
|
||||
import com.seibel.distanthorizons.common.wrappers.DependencySetup;
|
||||
import net.fabricmc.api.ClientModInitializer;
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents;
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public class FabricClientMain implements ClientModInitializer
|
||||
{
|
||||
public static FabricClientProxy client_proxy;
|
||||
public static FabricServerProxy server_proxy;
|
||||
|
||||
|
||||
// Do if implements ClientModInitializer
|
||||
// This loads the mod before minecraft loads which causes a lot of issues
|
||||
@Override
|
||||
public void onInitializeClient()
|
||||
{
|
||||
DependencySetup.createClientBindings();
|
||||
FabricMain.init();
|
||||
LodCommonMain.initConfig();
|
||||
|
||||
server_proxy = new FabricServerProxy(false);
|
||||
server_proxy.registerEvents();
|
||||
|
||||
client_proxy = new FabricClientProxy();
|
||||
client_proxy.registerEvents();
|
||||
|
||||
ClientLifecycleEvents.CLIENT_STARTED.register((mc) -> FabricMain.postInit());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
package com.seibel.distanthorizons.fabric;
|
||||
|
||||
import com.seibel.distanthorizons.common.AbstractModInitializer;
|
||||
import com.seibel.distanthorizons.common.rendering.SeamlessOverdraw;
|
||||
import com.seibel.distanthorizons.common.wrappers.McObjectConverter;
|
||||
import com.seibel.distanthorizons.common.wrappers.world.ClientLevelWrapper;
|
||||
@@ -31,37 +32,34 @@ import com.seibel.distanthorizons.core.config.Config;
|
||||
import com.seibel.distanthorizons.core.dependencyInjection.ModAccessorInjector;
|
||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||
import com.seibel.distanthorizons.core.pos.DhBlockPos;
|
||||
import com.seibel.distanthorizons.core.pos.DhChunkPos;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.ISodiumAccessor;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
|
||||
import com.seibel.distanthorizons.coreapi.ModInfo;
|
||||
import com.seibel.distanthorizons.fabric.wrappers.modAccessor.SodiumAccessor;
|
||||
//import io.netty.buffer.ByteBuf;
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
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.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.UseBlockCallback;
|
||||
import net.fabricmc.fabric.api.networking.v1.PacketSender;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.screens.TitleScreen;
|
||||
|
||||
#if MC_VER < MC_1_19_4
|
||||
import java.nio.FloatBuffer;
|
||||
#endif
|
||||
import java.util.HashSet;
|
||||
|
||||
import net.minecraft.client.multiplayer.ClientLevel;
|
||||
import net.minecraft.client.multiplayer.ClientPacketListener;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.InteractionResult;
|
||||
import net.minecraft.world.level.chunk.ChunkAccess;
|
||||
import net.minecraft.world.phys.HitResult;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
import org.lwjgl.opengl.GL15;
|
||||
|
||||
/**
|
||||
* This handles all events sent to the client,
|
||||
@@ -72,7 +70,7 @@ import org.lwjgl.opengl.GL15;
|
||||
* @version 2023-7-27
|
||||
*/
|
||||
@Environment(EnvType.CLIENT)
|
||||
public class FabricClientProxy
|
||||
public class FabricClientProxy implements AbstractModInitializer.IEventProxy
|
||||
{
|
||||
private final ClientApi clientApi = ClientApi.INSTANCE;
|
||||
private static final IMinecraftClientWrapper MC = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class);
|
||||
@@ -127,17 +125,20 @@ public class FabricClientProxy
|
||||
// if we have access to the server, use the chunk save event instead
|
||||
if (MC.clientConnectedToDedicatedServer())
|
||||
{
|
||||
// Since fabric doesn't have a client-side break-block API event, this is the next best thing
|
||||
ChunkAccess chunk = level.getChunk(blockPos);
|
||||
if (chunk != null)
|
||||
if (SharedApi.isChunkAtBlockPosAlreadyUpdating(blockPos.getX(), blockPos.getZ()))
|
||||
{
|
||||
LOGGER.trace("attack block at blockPos: " + blockPos);
|
||||
|
||||
IClientLevelWrapper wrappedLevel = ClientLevelWrapper.getWrapper((ClientLevel) level);
|
||||
SharedApi.INSTANCE.chunkBlockChangedEvent(
|
||||
new ChunkWrapper(chunk, level, wrappedLevel),
|
||||
wrappedLevel
|
||||
);
|
||||
// Since fabric doesn't have a client-side break-block API event, this is the next best thing
|
||||
ChunkAccess chunk = level.getChunk(blockPos);
|
||||
if (chunk != null)
|
||||
{
|
||||
LOGGER.trace("attack block at blockPos: " + blockPos);
|
||||
|
||||
IClientLevelWrapper wrappedLevel = ClientLevelWrapper.getWrapper((ClientLevel) level);
|
||||
SharedApi.INSTANCE.chunkBlockChangedEvent(
|
||||
new ChunkWrapper(chunk, level, wrappedLevel),
|
||||
wrappedLevel
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -151,20 +152,23 @@ public class FabricClientProxy
|
||||
// if we have access to the server, use the chunk save event instead
|
||||
if (MC.clientConnectedToDedicatedServer())
|
||||
{
|
||||
// Since fabric doesn't have a client-side place-block API event, this is the next best thing
|
||||
if (hitResult.getType() == HitResult.Type.BLOCK
|
||||
&& !hitResult.isInside())
|
||||
if (SharedApi.isChunkAtBlockPosAlreadyUpdating(hitResult.getBlockPos().getX(), hitResult.getBlockPos().getZ()))
|
||||
{
|
||||
ChunkAccess chunk = level.getChunk(hitResult.getBlockPos());
|
||||
if (chunk != null)
|
||||
// Since fabric doesn't have a client-side place-block API event, this is the next best thing
|
||||
if (hitResult.getType() == HitResult.Type.BLOCK
|
||||
&& !hitResult.isInside())
|
||||
{
|
||||
LOGGER.trace("use block at blockPos: " + hitResult.getBlockPos());
|
||||
|
||||
IClientLevelWrapper wrappedLevel = ClientLevelWrapper.getWrapper((ClientLevel) level);
|
||||
SharedApi.INSTANCE.chunkBlockChangedEvent(
|
||||
new ChunkWrapper(chunk, level, wrappedLevel),
|
||||
wrappedLevel
|
||||
);
|
||||
ChunkAccess chunk = level.getChunk(hitResult.getBlockPos());
|
||||
if (chunk != null)
|
||||
{
|
||||
LOGGER.trace("use block at blockPos: " + hitResult.getBlockPos());
|
||||
|
||||
IClientLevelWrapper wrappedLevel = ClientLevelWrapper.getWrapper((ClientLevel) level);
|
||||
SharedApi.INSTANCE.chunkBlockChangedEvent(
|
||||
new ChunkWrapper(chunk, level, wrappedLevel),
|
||||
wrappedLevel
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -187,9 +191,6 @@ public class FabricClientProxy
|
||||
// render event //
|
||||
//==============//
|
||||
|
||||
//Define this in the MixinLevelRenderer so that it works with sodium without any changes to the code
|
||||
// TODO: If all else is fine, can we remove these commented code
|
||||
// Client Render Level
|
||||
WorldRenderEvents.AFTER_SETUP.register((renderContext) ->
|
||||
{
|
||||
this.clientApi.renderLods(ClientLevelWrapper.getWrapper(renderContext.world()),
|
||||
@@ -203,9 +204,9 @@ public class FabricClientProxy
|
||||
{
|
||||
float[] matrixFloatArray = SeamlessOverdraw.overwriteMinecraftNearFarClipPlanes(renderContext.projectionMatrix(), renderContext.tickDelta());
|
||||
|
||||
#if MC_1_16_5
|
||||
#if MC_VER == MC_1_16_5
|
||||
SeamlessOverdraw.applyLegacyProjectionMatrix(matrixFloatArray);
|
||||
#elif PRE_MC_1_19_4
|
||||
#elif MC_VER < MC_1_19_4
|
||||
renderContext.projectionMatrix().load(FloatBuffer.wrap(matrixFloatArray));
|
||||
#else
|
||||
renderContext.projectionMatrix().set(matrixFloatArray);
|
||||
|
||||
@@ -1,56 +0,0 @@
|
||||
package com.seibel.distanthorizons.fabric;
|
||||
|
||||
import com.seibel.distanthorizons.common.LodCommonMain;
|
||||
import com.seibel.distanthorizons.common.wrappers.DependencySetup;
|
||||
import com.seibel.distanthorizons.common.wrappers.minecraft.MinecraftDedicatedServerWrapper;
|
||||
import com.seibel.distanthorizons.core.config.eventHandlers.presets.ThreadPresetConfigEventHandler;
|
||||
import com.seibel.distanthorizons.core.util.LodUtil;
|
||||
import net.fabricmc.api.DedicatedServerModInitializer;
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents;
|
||||
import net.minecraft.server.dedicated.DedicatedServer;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
@Environment(EnvType.SERVER)
|
||||
public class FabricDedicatedServerMain implements DedicatedServerModInitializer
|
||||
{
|
||||
private static final Logger LOGGER = LogManager.getLogger(FabricDedicatedServerMain.class.getSimpleName());
|
||||
|
||||
public static FabricServerProxy server_proxy;
|
||||
public boolean hasPostSetupDone = false;
|
||||
|
||||
@Override
|
||||
public void onInitializeServer()
|
||||
{
|
||||
DependencySetup.createServerBindings();
|
||||
FabricMain.init();
|
||||
|
||||
// FIXME this prevents returning uninitialized Config values
|
||||
// resulting from a circular reference mid-initialization in a static class
|
||||
// ThreadPresetConfigEventHandler <-> Config
|
||||
ThreadPresetConfigEventHandler.INSTANCE.toString();
|
||||
|
||||
server_proxy = new FabricServerProxy(true);
|
||||
server_proxy.registerEvents();
|
||||
|
||||
ServerLifecycleEvents.SERVER_STARTING.register((server) ->
|
||||
{
|
||||
if (this.hasPostSetupDone)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this.hasPostSetupDone = true;
|
||||
LodUtil.assertTrue(server instanceof DedicatedServer);
|
||||
|
||||
MinecraftDedicatedServerWrapper.INSTANCE.dedicatedServer = (DedicatedServer) server;
|
||||
LodCommonMain.initConfig();
|
||||
FabricMain.postInit();
|
||||
|
||||
LOGGER.info("Dedicated server initialized at " + server.getServerDirectory());
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -19,71 +19,51 @@
|
||||
|
||||
package com.seibel.distanthorizons.fabric;
|
||||
|
||||
import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiAfterDhInitEvent;
|
||||
import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiBeforeDhInitEvent;
|
||||
import com.seibel.distanthorizons.core.config.ConfigBase;
|
||||
import com.seibel.distanthorizons.core.jar.ModJarInfo;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.*;
|
||||
import com.seibel.distanthorizons.common.LodCommonMain;
|
||||
import com.seibel.distanthorizons.coreapi.ModInfo;
|
||||
import com.mojang.brigadier.CommandDispatcher;
|
||||
import com.seibel.distanthorizons.common.AbstractModInitializer;
|
||||
import com.seibel.distanthorizons.core.config.Config;
|
||||
import com.seibel.distanthorizons.coreapi.DependencyInjection.ApiEventInjector;
|
||||
import com.seibel.distanthorizons.core.config.ConfigBase;
|
||||
import com.seibel.distanthorizons.core.dependencyInjection.ModAccessorInjector;
|
||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||
import com.seibel.distanthorizons.fabric.wrappers.FabricDependencySetup;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.*;
|
||||
import com.seibel.distanthorizons.coreapi.ModInfo;
|
||||
import com.seibel.distanthorizons.fabric.wrappers.modAccessor.*;
|
||||
import net.fabricmc.api.ClientModInitializer;
|
||||
import net.fabricmc.api.DedicatedServerModInitializer;
|
||||
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents;
|
||||
import net.fabricmc.fabric.api.event.Event;
|
||||
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents;
|
||||
import net.minecraft.commands.CommandSourceStack;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import javax.swing.*;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* Initialize and setup the Mod. <br>
|
||||
* If you are looking for the real start of the mod
|
||||
* check out the ClientProxy.
|
||||
*
|
||||
* @author coolGi
|
||||
* @author Ran
|
||||
* @version 9-2-2022
|
||||
*/
|
||||
public class FabricMain
|
||||
public class FabricMain extends AbstractModInitializer implements ClientModInitializer, DedicatedServerModInitializer
|
||||
{
|
||||
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
|
||||
private static final ResourceLocation INITIAL_PHASE = ResourceLocation.tryParse("distanthorizons:dedicated_server_initial");
|
||||
|
||||
public static void postInit()
|
||||
|
||||
|
||||
@Override
|
||||
protected void createInitialBindings() { SingletonInjector.INSTANCE.bind(IModChecker.class, ModChecker.INSTANCE); }
|
||||
|
||||
@Override
|
||||
protected IEventProxy createClientProxy() { return new FabricClientProxy(); }
|
||||
|
||||
@Override
|
||||
protected IEventProxy createServerProxy(boolean isDedicated) { return new FabricServerProxy(isDedicated); }
|
||||
|
||||
@Override
|
||||
protected void initializeModCompat()
|
||||
{
|
||||
LOGGER.info("Post-Initializing Mod");
|
||||
FabricDependencySetup.runDelayedSetup();
|
||||
|
||||
if (Config.Client.Advanced.Graphics.Fog.disableVanillaFog.get() && SingletonInjector.INSTANCE.get(IModChecker.class).isModLoaded("bclib"))
|
||||
ModAccessorInjector.INSTANCE.get(IBCLibAccessor.class).setRenderCustomFog(false); // Remove BCLib's fog
|
||||
#if POST_MC_1_20_1
|
||||
if (SingletonInjector.INSTANCE.get(IModChecker.class).isModLoaded("sodium"))
|
||||
ModAccessorInjector.INSTANCE.get(ISodiumAccessor.class).setFogOcclusion(false); // FIXME: This is a tmp fix for sodium 0.5.0, and 0.5.1. This is fixed in sodium 0.5.2
|
||||
#endif
|
||||
|
||||
if (ConfigBase.INSTANCE == null)
|
||||
throw new IllegalStateException("Config was not initialized. Make sure to call LodCommonMain.initConfig() before calling this method.");
|
||||
|
||||
LOGGER.info("Mod Post-Initialized");
|
||||
}
|
||||
|
||||
|
||||
// This loads the mod after minecraft loads which doesn't causes a lot of issues
|
||||
public static void init()
|
||||
{
|
||||
ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeDhInitEvent.class, null);
|
||||
|
||||
LOGGER.info("Initializing Mod");
|
||||
LodCommonMain.startup(null);
|
||||
FabricDependencySetup.createInitialBindings();
|
||||
LOGGER.info(ModInfo.READABLE_NAME + ", Version: " + ModInfo.VERSION);
|
||||
|
||||
// Print git info (Useful for dev builds)
|
||||
LOGGER.info("DH Branch: " + ModJarInfo.Git_Branch);
|
||||
LOGGER.info("DH Commit: " + ModJarInfo.Git_Commit);
|
||||
LOGGER.info("DH Jar Build Source: " + ModJarInfo.Build_Source);
|
||||
|
||||
IModChecker modChecker = SingletonInjector.INSTANCE.get(IModChecker.class);
|
||||
if (modChecker.isModLoaded("sodium"))
|
||||
{
|
||||
@@ -92,36 +72,55 @@ public class FabricMain
|
||||
// If sodium is installed Indium is also necessary in order to use the Fabric rendering API
|
||||
if (!modChecker.isModLoaded("indium"))
|
||||
{
|
||||
// People don't read the crash logs!!!
|
||||
// So, just put a notification, so they hopefully realise what's the problem (and dont just open issues)
|
||||
System.setProperty("java.awt.headless", "false"); // Required to make it work
|
||||
JOptionPane.showMessageDialog(null, ModInfo.READABLE_NAME + " now relies on Indium to work with Sodium.\nPlease download Indium from https://modrinth.com/mod/indium", ModInfo.READABLE_NAME, JOptionPane.INFORMATION_MESSAGE);
|
||||
|
||||
IMinecraftClientWrapper mc = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class);
|
||||
String errorMessage = "loading Distant Horizons. Distant Horizons requires Indium in order to run with Sodium.";
|
||||
String exceptionError = "Distant Horizons conditional mod Exception";
|
||||
mc.crashMinecraft(errorMessage, new Exception(exceptionError));
|
||||
}
|
||||
}
|
||||
if (modChecker.isModLoaded("starlight"))
|
||||
{
|
||||
ModAccessorInjector.INSTANCE.bind(IStarlightAccessor.class, new StarlightAccessor());
|
||||
}
|
||||
if (modChecker.isModLoaded("optifine"))
|
||||
{
|
||||
ModAccessorInjector.INSTANCE.bind(IOptifineAccessor.class, new OptifineAccessor());
|
||||
}
|
||||
if (modChecker.isModLoaded("bclib"))
|
||||
{
|
||||
ModAccessorInjector.INSTANCE.bind(IBCLibAccessor.class, new BCLibAccessor());
|
||||
}
|
||||
|
||||
#if MC_1_16_5 || MC_1_18_2 || MC_1_19_2 || MC_1_19_4 || MC_1_20_1
|
||||
// 1.17.1 won't support this since there isn't a matching Iris version
|
||||
if (modChecker.isModLoaded("iris"))
|
||||
{
|
||||
ModAccessorInjector.INSTANCE.bind(IIrisAccessor.class, new IrisAccessor());
|
||||
}
|
||||
this.tryCreateModCompatAccessor("starlight", IStarlightAccessor.class, StarlightAccessor::new);
|
||||
this.tryCreateModCompatAccessor("optifine", IOptifineAccessor.class, OptifineAccessor::new);
|
||||
this.tryCreateModCompatAccessor("bclib", IBCLibAccessor.class, BCLibAccessor::new);
|
||||
#if MC_VER >= MC_1_19_4
|
||||
// 1.19.4 is the lowest version Iris supports DH
|
||||
this.tryCreateModCompatAccessor("iris", IIrisAccessor.class, IrisAccessor::new);
|
||||
#endif
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void subscribeRegisterCommandsEvent(Consumer<CommandDispatcher<CommandSourceStack>> eventHandler) { }
|
||||
|
||||
@Override
|
||||
protected void subscribeClientStartedEvent(Runnable eventHandler) { ClientLifecycleEvents.CLIENT_STARTED.register((mc) -> eventHandler.run()); }
|
||||
|
||||
@Override
|
||||
protected void subscribeServerStartingEvent(Consumer<MinecraftServer> eventHandler)
|
||||
{
|
||||
ServerLifecycleEvents.SERVER_STARTING.addPhaseOrdering(INITIAL_PHASE, Event.DEFAULT_PHASE);
|
||||
ServerLifecycleEvents.SERVER_STARTING.register(INITIAL_PHASE, eventHandler::accept);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void runDelayedSetup()
|
||||
{
|
||||
SingletonInjector.INSTANCE.runDelayedSetup();
|
||||
|
||||
if (Config.Client.Advanced.Graphics.Fog.disableVanillaFog.get() && SingletonInjector.INSTANCE.get(IModChecker.class).isModLoaded("bclib"))
|
||||
ModAccessorInjector.INSTANCE.get(IBCLibAccessor.class).setRenderCustomFog(false); // Remove BCLib's fog
|
||||
|
||||
#if MC_VER >= MC_1_20_1
|
||||
if (SingletonInjector.INSTANCE.get(IModChecker.class).isModLoaded("sodium"))
|
||||
ModAccessorInjector.INSTANCE.get(ISodiumAccessor.class).setFogOcclusion(false); // FIXME: This is a tmp fix for sodium 0.5.0, and 0.5.1. This is fixed in sodium 0.5.2
|
||||
#endif
|
||||
|
||||
LOGGER.info(ModInfo.READABLE_NAME + " Initialized");
|
||||
|
||||
ApiEventInjector.INSTANCE.fireAllEvents(DhApiAfterDhInitEvent.class, null);
|
||||
if (ConfigBase.INSTANCE == null)
|
||||
throw new IllegalStateException("Config was not initialized. Make sure to call LodCommonMain.initConfig() before calling this method.");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
package com.seibel.distanthorizons.fabric;
|
||||
|
||||
import com.seibel.distanthorizons.common.AbstractModInitializer;
|
||||
import com.seibel.distanthorizons.common.wrappers.chunk.ChunkWrapper;
|
||||
import com.seibel.distanthorizons.common.wrappers.misc.ServerPlayerWrapper;
|
||||
import com.seibel.distanthorizons.common.wrappers.world.ClientLevelWrapper;
|
||||
import com.seibel.distanthorizons.common.wrappers.world.ServerLevelWrapper;
|
||||
import com.seibel.distanthorizons.common.wrappers.worldGeneration.BatchGenerationEnvironment;
|
||||
import com.seibel.distanthorizons.core.api.internal.ClientApi;
|
||||
import com.seibel.distanthorizons.core.api.internal.ServerApi;
|
||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
|
||||
@@ -32,7 +32,7 @@ import java.util.function.Supplier;
|
||||
* @author Tomlee
|
||||
* @version 5-11-2022
|
||||
*/
|
||||
public class FabricServerProxy
|
||||
public class FabricServerProxy implements AbstractModInitializer.IEventProxy
|
||||
{
|
||||
private static final ServerApi SERVER_API = ServerApi.INSTANCE;
|
||||
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
|
||||
|
||||
+4
-4
@@ -24,7 +24,7 @@ import com.seibel.distanthorizons.common.wrappers.world.ClientLevelWrapper;
|
||||
import com.seibel.distanthorizons.core.api.internal.ClientApi;
|
||||
import com.seibel.distanthorizons.core.api.internal.SharedApi;
|
||||
import net.minecraft.client.multiplayer.ClientLevel;
|
||||
#if POST_MC_1_18_2
|
||||
#if MC_VER >= MC_1_18_2
|
||||
#endif
|
||||
import net.minecraft.world.level.chunk.LevelChunk;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
@@ -44,14 +44,14 @@ public class MixinClientLevel
|
||||
// //Moved to MixinClientPacketListener
|
||||
// @Inject(method = "<init>", at = @At("TAIL"))
|
||||
// private void loadWorldEvent(ClientPacketListener clientPacketListener, ClientLevel.ClientLevelData clientLevelData, ResourceKey resourceKey,
|
||||
// #if POST_MC_1_18_2 Holder holder, #else DimensionType dimensionType, #endif int i,
|
||||
// #if POST_MC_1_18_2 int j, #endif Supplier supplier, LevelRenderer levelRenderer, boolean bl, long l, CallbackInfo ci)
|
||||
// #if MC_VER >= MC_1_18_2 Holder holder, #else DimensionType dimensionType, #endif int i,
|
||||
// #if MC_VER >= MC_1_18_2 int j, #endif Supplier supplier, LevelRenderer levelRenderer, boolean bl, long l, CallbackInfo ci)
|
||||
// {
|
||||
// ClientApi.INSTANCE.clientLevelLoadEvent(WorldWrapper.getWorldWrapper((ClientLevel)(Object)this));
|
||||
// }
|
||||
|
||||
// Moved to overriding the enableChunkLight(...) method over at ClientPacketListener for 1.20+
|
||||
#if POST_MC_1_18_2 && PRE_MC_1_20_1 // Only the setLightReady is only available after 1.18. This ensures the light data is ready.
|
||||
#if MC_VER >= MC_1_18_2 && MC_VER < MC_1_20_1 // Only the setLightReady is only available after 1.18. This ensures the light data is ready.
|
||||
@Inject(method = "setLightReady", at = @At("HEAD"))
|
||||
private void onChunkLightReady(int x, int z, CallbackInfo ci)
|
||||
{
|
||||
|
||||
+7
-8
@@ -11,7 +11,7 @@ import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
#if POST_MC_1_20_1
|
||||
#if MC_VER >= MC_1_20_1
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
|
||||
import net.minecraft.world.level.chunk.LevelChunk;
|
||||
import com.seibel.distanthorizons.common.wrappers.chunk.ChunkWrapper;
|
||||
@@ -27,26 +27,25 @@ public class MixinClientPacketListener
|
||||
void onHandleLoginEnd(CallbackInfo ci) { ClientApi.INSTANCE.onClientOnlyConnected(); }
|
||||
|
||||
@Inject(method = "handleRespawn", at = @At("HEAD"))
|
||||
void onHandleRespawnStart(CallbackInfo ci) { ClientApi.INSTANCE.clientLevelUnloadEvent(ClientLevelWrapper.getWrapper(level)); }
|
||||
void onHandleRespawnStart(CallbackInfo ci) { ClientApi.INSTANCE.clientLevelUnloadEvent(ClientLevelWrapper.getWrapper(this.level)); }
|
||||
@Inject(method = "handleRespawn", at = @At("RETURN"))
|
||||
void onHandleRespawnEnd(CallbackInfo ci) { ClientApi.INSTANCE.clientLevelLoadEvent(ClientLevelWrapper.getWrapper(level)); }
|
||||
void onHandleRespawnEnd(CallbackInfo ci) { ClientApi.INSTANCE.clientLevelLoadEvent(ClientLevelWrapper.getWrapper(this.level)); }
|
||||
|
||||
#if PRE_MC_1_19_4
|
||||
#if MC_VER < MC_1_19_4
|
||||
@Inject(method = "cleanup", at = @At("HEAD"))
|
||||
#else
|
||||
@Inject(method = "close", at = @At("HEAD"))
|
||||
#endif
|
||||
void onCleanupStart(CallbackInfo ci)
|
||||
{
|
||||
// TODO Is this even needed here?
|
||||
if (level != null)
|
||||
if (this.level != null)
|
||||
{
|
||||
ClientApi.INSTANCE.clientLevelUnloadEvent(ClientLevelWrapper.getWrapper(level));
|
||||
ClientApi.INSTANCE.clientLevelUnloadEvent(ClientLevelWrapper.getWrapper(this.level));
|
||||
}
|
||||
ClientApi.INSTANCE.onClientOnlyDisconnected();
|
||||
}
|
||||
|
||||
#if POST_MC_1_20_1
|
||||
#if MC_VER >= MC_1_20_1
|
||||
@Inject(method = "enableChunkLight", at = @At("TAIL"))
|
||||
void onEnableChunkLight(LevelChunk chunk, int x, int z, CallbackInfo ci)
|
||||
{
|
||||
|
||||
+36
-9
@@ -1,3 +1,22 @@
|
||||
/*
|
||||
* This file is part of the Distant Horizons mod
|
||||
* licensed under the GNU LGPL v3 License.
|
||||
*
|
||||
* Copyright (C) 2020-2023 James Seibel
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.seibel.distanthorizons.fabric.mixins.client;
|
||||
|
||||
|
||||
@@ -6,37 +25,45 @@ import com.seibel.distanthorizons.common.wrappers.minecraft.MinecraftRenderWrapp
|
||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper;
|
||||
import net.minecraft.client.renderer.LightTexture;
|
||||
import com.seibel.distanthorizons.common.util.ILightTextureMarker;
|
||||
import net.minecraft.client.renderer.texture.DynamicTexture;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
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.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
@Mixin(DynamicTexture.class)
|
||||
public class MixinLightmap
|
||||
public class MixinDynamicTexture implements ILightTextureMarker
|
||||
{
|
||||
/** Used to prevent accidentally using other dynamic textures as a lightmap */
|
||||
@Unique
|
||||
private boolean isLightTexture = false;
|
||||
|
||||
@Shadow
|
||||
@Final
|
||||
private NativeImage pixels;
|
||||
|
||||
@Inject(method = "Lnet/minecraft/client/renderer/texture/DynamicTexture;upload()V", at = @At("HEAD"), cancellable = true)
|
||||
@Inject(method = "upload()V", at = @At("HEAD"))
|
||||
public void updateLightTexture(CallbackInfo ci)
|
||||
{
|
||||
// since the light map is always updated on the client render thread we should be able to access the client level at the same time
|
||||
IMinecraftClientWrapper mc = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class);
|
||||
if (
|
||||
mc == null ||
|
||||
mc.getWrappedClientLevel() == null
|
||||
)
|
||||
if (!this.isLightTexture
|
||||
|| mc == null
|
||||
|| mc.getWrappedClientLevel() == null
|
||||
)
|
||||
{
|
||||
return;
|
||||
IClientLevelWrapper clientLevel = mc.getWrappedClientLevel();
|
||||
}
|
||||
|
||||
//ApiShared.LOGGER.info("Lightmap update");
|
||||
IClientLevelWrapper clientLevel = mc.getWrappedClientLevel();
|
||||
MinecraftRenderWrapper.INSTANCE.updateLightmap(this.pixels, clientLevel);
|
||||
}
|
||||
|
||||
public void markLightTexture() { this.isLightTexture = true; }
|
||||
|
||||
}
|
||||
+4
-4
@@ -35,7 +35,7 @@ import net.minecraft.client.renderer.FogRenderer.FogMode;
|
||||
import net.minecraft.world.effect.MobEffects;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
#if PRE_MC_1_17_1
|
||||
#if MC_VER < MC_1_17_1
|
||||
import net.minecraft.world.level.material.FluidState;
|
||||
#else
|
||||
import net.minecraft.world.level.material.FogType;
|
||||
@@ -50,14 +50,14 @@ public class MixinFogRenderer
|
||||
private static final float A_EVEN_LARGER_VALUE = 42069420694206942069.F;
|
||||
|
||||
@Inject(at = @At("RETURN"), method = "setupFog")
|
||||
#if PRE_MC_1_19_2
|
||||
#if MC_VER < MC_1_19_2
|
||||
private static void disableSetupFog(Camera camera, FogMode fogMode, float f, boolean bl, CallbackInfo callback)
|
||||
{
|
||||
#else
|
||||
private static void disableSetupFog(Camera camera, FogMode fogMode, float f, boolean bl, float g, CallbackInfo callback)
|
||||
{
|
||||
#endif
|
||||
#if PRE_MC_1_17_1
|
||||
#if MC_VER < MC_1_17_1
|
||||
FluidState fluidState = camera.getFluidInCamera();
|
||||
boolean cameraNotInFluid = fluidState.isEmpty();
|
||||
#else
|
||||
@@ -71,7 +71,7 @@ public class MixinFogRenderer
|
||||
&& !SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class).isFogStateSpecial()
|
||||
&& Config.Client.Advanced.Graphics.Fog.disableVanillaFog.get())
|
||||
{
|
||||
#if PRE_MC_1_17_1
|
||||
#if MC_VER < MC_1_17_1
|
||||
RenderSystem.fogStart(A_REALLY_REALLY_BIG_VALUE);
|
||||
RenderSystem.fogEnd(A_EVEN_LARGER_VALUE);
|
||||
#else
|
||||
|
||||
+1
-1
@@ -16,7 +16,7 @@ public class MixinGameRenderer
|
||||
private static final Logger LOGGER = LogManager.getLogger(MixinGameRenderer.class.getSimpleName());
|
||||
|
||||
|
||||
#if POST_MC_1_17_1
|
||||
#if MC_VER >= MC_1_17_1
|
||||
// FIXME: This I think will dup multiple renderStartupEvent calls...
|
||||
@Inject(method = {"reloadShaders", "preloadUiShader"}, at = @At("TAIL"))
|
||||
public void onStartupShaders(CallbackInfo ci)
|
||||
|
||||
+37
-30
@@ -20,15 +20,20 @@
|
||||
package com.seibel.distanthorizons.fabric.mixins.client;
|
||||
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
#if PRE_MC_1_19_4
|
||||
#if MC_VER < MC_1_19_4
|
||||
import com.mojang.math.Matrix4f;
|
||||
#else
|
||||
import net.minecraft.client.Camera;
|
||||
import net.minecraft.client.renderer.GameRenderer;
|
||||
import net.minecraft.client.renderer.LightTexture;
|
||||
import org.joml.Matrix4f;
|
||||
#endif
|
||||
import com.seibel.distanthorizons.common.wrappers.chunk.ChunkWrapper;
|
||||
import com.seibel.distanthorizons.common.wrappers.McObjectConverter;
|
||||
import com.seibel.distanthorizons.common.wrappers.world.ClientLevelWrapper;
|
||||
import com.seibel.distanthorizons.core.api.internal.ClientApi;
|
||||
import com.seibel.distanthorizons.coreapi.util.math.Mat4f;
|
||||
import net.minecraft.client.Camera;
|
||||
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.Camera;
|
||||
import net.minecraft.client.multiplayer.ClientLevel;
|
||||
@@ -37,6 +42,7 @@ import net.minecraft.client.renderer.LevelRenderer;
|
||||
import net.minecraft.client.renderer.LightTexture;
|
||||
import net.minecraft.client.renderer.RenderType;
|
||||
import net.minecraft.world.level.lighting.LevelLightEngine;
|
||||
import org.lwjgl.opengl.GL15;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
@@ -62,39 +68,18 @@ public class MixinLevelRenderer
|
||||
{
|
||||
@Shadow
|
||||
private ClientLevel level;
|
||||
@Unique
|
||||
private static float previousPartialTicks = 0;
|
||||
|
||||
// Inject rendering at first call to renderChunkLayer
|
||||
// HEAD or RETURN
|
||||
#if PRE_MC_1_17_1
|
||||
@Inject(at = @At("RETURN"), method = "renderSky(Lcom/mojang/blaze3d/vertex/PoseStack;F)V")
|
||||
private void renderSky(PoseStack matrixStackIn, float partialTicks, CallbackInfo callback)
|
||||
{
|
||||
// get the partial ticks since renderBlockLayer doesn't
|
||||
// have access to them
|
||||
previousPartialTicks = partialTicks;
|
||||
}
|
||||
#else
|
||||
@Inject(method = "renderClouds", at = @At("HEAD"), cancellable = true)
|
||||
public void renderClouds(PoseStack poseStack, Matrix4f projectionMatrix, float tickDelta, double cameraX, double cameraY, double cameraZ, CallbackInfo ci) {
|
||||
// get the partial ticks since renderChunkLayer doesn't
|
||||
// have access to them
|
||||
previousPartialTicks = tickDelta;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if PRE_MC_1_17_1
|
||||
#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",
|
||||
cancellable = true)
|
||||
private void renderChunkLayer(RenderType renderType, PoseStack matrixStackIn, double xIn, double yIn, double zIn, CallbackInfo callback)
|
||||
#elif PRE_MC_1_19_4
|
||||
#elif MC_VER < MC_1_19_4
|
||||
@Inject(at = @At("HEAD"),
|
||||
method = "renderChunkLayer(Lnet/minecraft/client/renderer/RenderType;Lcom/mojang/blaze3d/vertex/PoseStack;DDDLcom/mojang/math/Matrix4f;)V",
|
||||
cancellable = true)
|
||||
private void renderChunkLayer(RenderType renderType, PoseStack modelViewMatrixStack, double cameraXBlockPos, double cameraYBlockPos, double cameraZBlockPos, Matrix4f projectionMatrix, CallbackInfo callback)
|
||||
#elif PRE_MC_1_20_2
|
||||
#elif MC_VER < MC_1_20_2
|
||||
@Inject(at = @At("HEAD"),
|
||||
method = "renderChunkLayer(Lnet/minecraft/client/renderer/RenderType;Lcom/mojang/blaze3d/vertex/PoseStack;DDDLorg/joml/Matrix4f;)V",
|
||||
cancellable = true)
|
||||
@@ -106,6 +91,28 @@ public class MixinLevelRenderer
|
||||
private void renderChunkLayer(RenderType renderType, PoseStack modelViewMatrixStack, double camX, double camY, double camZ, Matrix4f projectionMatrix, CallbackInfo callback)
|
||||
#endif
|
||||
{
|
||||
#if MC_VER == MC_1_16_5
|
||||
// get the matrices from the OpenGL fixed pipeline
|
||||
float[] mcProjMatrixRaw = new float[16];
|
||||
GL15.glGetFloatv(GL15.GL_PROJECTION_MATRIX, mcProjMatrixRaw);
|
||||
Mat4f mcProjectionMatrix = new Mat4f(mcProjMatrixRaw);
|
||||
mcProjectionMatrix.transpose();
|
||||
|
||||
Mat4f mcModelViewMatrix = McObjectConverter.Convert(matrixStackIn.last().pose());
|
||||
|
||||
#else
|
||||
// get the matrices directly from MC
|
||||
Mat4f mcModelViewMatrix = McObjectConverter.Convert(modelViewMatrixStack.last().pose());
|
||||
Mat4f mcProjectionMatrix = McObjectConverter.Convert(projectionMatrix);
|
||||
#endif
|
||||
|
||||
if (renderType.equals(RenderType.translucent())) {
|
||||
ClientApi.INSTANCE.renderDeferredLods(ClientLevelWrapper.getWrapper(this.level),
|
||||
mcModelViewMatrix,
|
||||
mcProjectionMatrix,
|
||||
Minecraft.getInstance().getFrameTime());
|
||||
}
|
||||
|
||||
// FIXME completely disables rendering when sodium is installed
|
||||
if (Config.Client.Advanced.Debugging.lodOnlyMode.get())
|
||||
{
|
||||
@@ -113,10 +120,10 @@ public class MixinLevelRenderer
|
||||
}
|
||||
}
|
||||
|
||||
#if PRE_MC_1_19_4
|
||||
#if MC_VER < MC_1_19_4
|
||||
@Inject(at = @At(value = "TAIL", target = "Lnet/minecraft/world/level/lighting/LevelLightEngine;runUpdates(IZZ)I"), method = "renderLevel")
|
||||
public void callAfterRunUpdates(PoseStack poseStack, float partialTick, long finishNanoTime, boolean renderBlockOutline, Camera camera, GameRenderer gameRenderer, LightTexture lightTexture, Matrix4f projectionMatrix, CallbackInfo ci)
|
||||
#elif PRE_MC_1_20_1
|
||||
#elif MC_VER < MC_1_20_1
|
||||
@Inject(at = @At(value = "TAIL", target = "Lnet/minecraft/world/level/lighting/LevelLightEngine;runUpdates(IZZ)I"), method = "renderLevel")
|
||||
public void callAfterRunUpdates(PoseStack poseStack, float partialTick, long finishNanoTime, boolean renderBlockOutline, Camera camera, GameRenderer gameRenderer, LightTexture lightTexture, Matrix4f projectionMatrix, CallbackInfo ci)
|
||||
#else
|
||||
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* This file is part of the Distant Horizons mod
|
||||
* licensed under the GNU LGPL v3 License.
|
||||
*
|
||||
* Copyright (C) 2020-2023 James Seibel
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.seibel.distanthorizons.fabric.mixins.client;
|
||||
|
||||
|
||||
import com.seibel.distanthorizons.common.util.ILightTextureMarker;
|
||||
import net.minecraft.client.renderer.LightTexture;
|
||||
import net.minecraft.client.renderer.texture.DynamicTexture;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
@Mixin(LightTexture.class)
|
||||
public class MixinLightTexture
|
||||
{
|
||||
@Shadow
|
||||
@Final
|
||||
private DynamicTexture lightTexture;
|
||||
|
||||
@Inject(method = "<init>", at = @At("RETURN"))
|
||||
public void markLightTexture(CallbackInfo ci)
|
||||
{
|
||||
//
|
||||
((ILightTextureMarker) this.lightTexture).markLightTexture();
|
||||
}
|
||||
|
||||
}
|
||||
+3
-3
@@ -25,8 +25,8 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
@Mixin(Minecraft.class)
|
||||
public class MixinMinecraft
|
||||
{
|
||||
#if PRE_MC_1_20_2
|
||||
#if MC_1_20_1
|
||||
#if MC_VER < MC_1_20_2
|
||||
#if MC_VER == MC_1_20_1
|
||||
@Redirect(
|
||||
method = "Lnet/minecraft/client/Minecraft;setInitialScreen(Lcom/mojang/realmsclient/client/RealmsClient;Lnet/minecraft/server/packs/resources/ReloadInstance;Lnet/minecraft/client/main/GameConfig$QuickPlayData;)V",
|
||||
at = @At(value = "INVOKE", target = "Lnet/minecraft/client/Minecraft;setScreen(Lnet/minecraft/client/gui/screens/Screen;)V")
|
||||
@@ -61,7 +61,7 @@ public class MixinMinecraft
|
||||
}
|
||||
#endif
|
||||
|
||||
#if POST_MC_1_20_2
|
||||
#if MC_VER >= MC_1_20_2
|
||||
@Redirect(
|
||||
method = "Lnet/minecraft/client/Minecraft;onGameLoadFinished(Lnet/minecraft/client/Minecraft$GameLoadCookie;)V",
|
||||
at = @At(value = "INVOKE", target = "Ljava/lang/Runnable;run()V")
|
||||
|
||||
+3
-3
@@ -26,7 +26,7 @@ import com.seibel.distanthorizons.core.config.Config;
|
||||
import net.minecraft.client.gui.screens.OptionsScreen;
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
import net.minecraft.network.chat.Component;
|
||||
#if PRE_MC_1_19_2
|
||||
#if MC_VER < MC_1_19_2
|
||||
import net.minecraft.network.chat.TranslatableComponent;
|
||||
#endif
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
@@ -57,7 +57,7 @@ public class MixinOptionsScreen extends Screen
|
||||
private void lodconfig$init(CallbackInfo ci)
|
||||
{
|
||||
if (Config.Client.optionsButton.get())
|
||||
this. #if PRE_MC_1_17_1 addButton #else addRenderableWidget #endif
|
||||
this. #if MC_VER < MC_1_17_1 addButton #else addRenderableWidget #endif
|
||||
(new TexturedButtonWidget(
|
||||
// Where the button is on the screen
|
||||
this.width / 2 - 180, this.height / 6 - 12,
|
||||
@@ -71,7 +71,7 @@ public class MixinOptionsScreen extends Screen
|
||||
// For now it goes to the client option by default
|
||||
(buttonWidget) -> Objects.requireNonNull(minecraft).setScreen(GetConfigScreen.getScreen(this)),
|
||||
// Add a title to the utton
|
||||
#if PRE_MC_1_19_2
|
||||
#if MC_VER < MC_1_19_2
|
||||
new TranslatableComponent(ModInfo.ID + ".title")));
|
||||
#else
|
||||
Component.translatable(ModInfo.ID + ".title")));
|
||||
|
||||
+1
-1
@@ -16,7 +16,7 @@ import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
public class MixinTextureUtil
|
||||
{
|
||||
@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_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)
|
||||
{
|
||||
float biasValue = Config.Client.Advanced.Graphics.AdvancedGraphics.lodBias.get().floatValue();
|
||||
|
||||
+1
-1
@@ -31,7 +31,7 @@ import org.spongepowered.asm.mixin.Mixin;
|
||||
@Deprecated // TODO: Not sure if this is needed anymore
|
||||
public class MixinServerLevel
|
||||
{
|
||||
// #if PRE_MC_1_17_1
|
||||
// #if MC_VER < MC_1_17_1
|
||||
// @Inject(method = "save", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ServerChunkCache;save(Z)V", shift = At.Shift.AFTER))
|
||||
// private void saveWorldEvent(ProgressListener progressListener, boolean bl, boolean bl2, CallbackInfo ci) {
|
||||
// Main.client_proxy.worldSaveEvent();
|
||||
|
||||
+2
-2
@@ -2,7 +2,7 @@ package com.seibel.distanthorizons.fabric.mixins.mods.sodium;
|
||||
|
||||
/* Removed since DH now uses Indium so we can use the Fabric rendering API instead
|
||||
|
||||
#if POST_MC_1_20_1
|
||||
#if MC_VER >= MC_1_20_1
|
||||
// Sodium 0.5
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.seibel.distanthorizons.core.api.internal.ClientApi;
|
||||
@@ -55,7 +55,7 @@ public class MixinSodiumRenderer
|
||||
|
||||
}
|
||||
|
||||
#elif POST_MC_1_17_1
|
||||
#elif MC_VER >= MC_1_17_1
|
||||
// Sodium 0.3 to 0.4
|
||||
import com.seibel.distanthorizons.core.api.internal.ClientApi;
|
||||
import com.seibel.distanthorizons.core.dependencyInjection.ModAccessorInjector;
|
||||
|
||||
+1
-1
@@ -22,7 +22,7 @@ package com.seibel.distanthorizons.fabric.mixins.server;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import net.minecraft.world.level.chunk.ChunkGenerator;
|
||||
|
||||
#if PRE_MC_1_18_2
|
||||
#if MC_VER < MC_1_18_2
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
|
||||
|
||||
+56
-46
@@ -28,56 +28,66 @@ public class MixinChunkMap
|
||||
@Final
|
||||
ServerLevel level;
|
||||
|
||||
@Inject(method = "save", at = @At(value = "INVOKE", target = CHUNK_SERIALIZER_WRITE))
|
||||
// firing at INVOKE causes issues with C2ME and is probably unnecessary since we
|
||||
// don't need the chunk(s) before MC has finished saving them
|
||||
@Inject(method = "save", at = @At(value = "RETURN", target = CHUNK_SERIALIZER_WRITE))
|
||||
private void onChunkSave(ChunkAccess chunk, CallbackInfoReturnable<Boolean> ci)
|
||||
{
|
||||
//=====================================//
|
||||
// corrupt/incomplete chunk validation //
|
||||
//=====================================//
|
||||
|
||||
// MC has a tendency to try saving incomplete or corrupted chunks (which show up as empty or black chunks)
|
||||
// this logic should prevent that from happening
|
||||
#if MC_1_16_5 || MC_1_17_1
|
||||
if (chunk.isUnsaved() || chunk.getUpgradeData() != null || !chunk.isLightCorrect())
|
||||
// true means a chunk was saved to disk
|
||||
if (ci.getReturnValue())
|
||||
{
|
||||
return;
|
||||
// TODO is this validation necessary since we are checking above if
|
||||
// the callback return value should state if the chunk was actually saved or not?
|
||||
// Do we trust it to always be correct?
|
||||
|
||||
//=====================================//
|
||||
// corrupt/incomplete chunk validation //
|
||||
//=====================================//
|
||||
|
||||
// MC has a tendency to try saving incomplete or corrupted chunks (which show up as empty or black chunks)
|
||||
// this logic should prevent that from happening
|
||||
#if MC_VER == MC_1_16_5 || MC_VER == MC_1_17_1
|
||||
if (chunk.isUnsaved() || chunk.getUpgradeData() != null || !chunk.isLightCorrect())
|
||||
{
|
||||
return;
|
||||
}
|
||||
#else
|
||||
if (chunk.isUnsaved() || chunk.isUpgrading() || !chunk.isLightCorrect())
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
//==================//
|
||||
// biome validation //
|
||||
//==================//
|
||||
|
||||
// some chunks may be missing their biomes, which cause issues when attempting to save them
|
||||
#if MC_VER == MC_1_16_5 || MC_VER == MC_1_17_1
|
||||
if (chunk.getBiomes() == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
#else
|
||||
try
|
||||
{
|
||||
// this will throw an exception if the biomes aren't set up
|
||||
chunk.getNoiseBiome(0,0,0);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
ServerApi.INSTANCE.serverChunkSaveEvent(
|
||||
new ChunkWrapper(chunk, this.level, ServerLevelWrapper.getWrapper(this.level)),
|
||||
ServerLevelWrapper.getWrapper(this.level)
|
||||
);
|
||||
}
|
||||
#else
|
||||
if (chunk.isUnsaved() || chunk.isUpgrading() || !chunk.isLightCorrect())
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
//==================//
|
||||
// biome validation //
|
||||
//==================//
|
||||
|
||||
// some chunks may be missing their biomes, which cause issues when attempting to save them
|
||||
#if MC_1_16_5 || MC_1_17_1
|
||||
if (chunk.getBiomes() == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
#else
|
||||
try
|
||||
{
|
||||
// this will throw an exception if the biomes aren't set up
|
||||
chunk.getNoiseBiome(0,0,0);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
ServerApi.INSTANCE.serverChunkSaveEvent(
|
||||
new ChunkWrapper(chunk, this.level, ServerLevelWrapper.getWrapper(this.level)),
|
||||
ServerLevelWrapper.getWrapper(this.level)
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+2
-2
@@ -50,7 +50,7 @@ public class MixinUtilBackgroundThread
|
||||
}
|
||||
}
|
||||
|
||||
#if POST_MC_1_17_1
|
||||
#if MC_VER >= MC_1_17_1
|
||||
@Inject(method = "wrapThreadWithTaskName(Ljava/lang/String;Ljava/lang/Runnable;)Ljava/lang/Runnable;",
|
||||
at = @At("HEAD"), cancellable = true)
|
||||
private static void overrideUtil$wrapThreadWithTaskName(String string, Runnable r, CallbackInfoReturnable<Runnable> ci)
|
||||
@@ -62,7 +62,7 @@ public class MixinUtilBackgroundThread
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if POST_MC_1_18_2
|
||||
#if MC_VER >= MC_1_18_2
|
||||
@Inject(method = "wrapThreadWithTaskName(Ljava/lang/String;Ljava/util/function/Supplier;)Ljava/util/function/Supplier;",
|
||||
at = @At("HEAD"), cancellable = true)
|
||||
private static void overrideUtil$wrapThreadWithTaskNameForSupplier(String string, Supplier<?> r, CallbackInfoReturnable<Supplier<?>> ci)
|
||||
|
||||
+1
-1
@@ -22,7 +22,7 @@ package com.seibel.distanthorizons.fabric.mixins.server.unsafe;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
|
||||
//FIXME: Is this still needed?
|
||||
#if POST_MC_1_18_2
|
||||
#if MC_VER >= MC_1_18_2
|
||||
|
||||
import net.minecraft.util.ThreadingDetector;
|
||||
import org.spongepowered.asm.mixin.Mutable;
|
||||
|
||||
+3
-3
@@ -1,8 +1,8 @@
|
||||
package com.seibel.distanthorizons.fabric.wrappers.modAccessor;
|
||||
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IBCLibAccessor;
|
||||
#if MC_1_16_5 || MC_1_17_1
|
||||
#elif MC_1_18_2
|
||||
#if MC_VER == MC_1_16_5 || MC_VER == MC_1_17_1 || MC_VER == MC_1_20_4 // These versions either don't have BCLib, or the implementation is different
|
||||
#elif MC_VER == MC_1_18_2
|
||||
import ru.bclib.config.ClientConfig;
|
||||
import ru.bclib.config.Configs;
|
||||
#else
|
||||
@@ -17,7 +17,7 @@ public class BCLibAccessor implements IBCLibAccessor
|
||||
|
||||
public void setRenderCustomFog(boolean newValue)
|
||||
{
|
||||
#if !(MC_1_16_5 || MC_1_17_1) // 1.16 and 1.17 don't have "ClientConfig.CUSTOM_FOG_RENDERING"
|
||||
#if !(MC_VER == MC_1_16_5 || MC_VER == MC_1_17_1 || MC_VER == MC_1_20_4) // These versions either don't have BCLib, or the implementation is different
|
||||
|
||||
// Change the value of CUSTOM_FOG_RENDERING in the bclib client config
|
||||
// This disabled fog from rendering within bclib
|
||||
|
||||
+1
-1
@@ -19,7 +19,7 @@
|
||||
|
||||
package com.seibel.distanthorizons.fabric.wrappers.modAccessor;
|
||||
|
||||
#if MC_1_16_5 || MC_1_18_2 || MC_1_19_2 || MC_1_19_4 || MC_1_20_1
|
||||
#if MC_VER >= MC_1_19_4
|
||||
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IIrisAccessor;
|
||||
import net.coderbot.iris.Iris;
|
||||
|
||||
+8
@@ -22,6 +22,8 @@ package com.seibel.distanthorizons.fabric.wrappers.modAccessor;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IModChecker;
|
||||
import net.fabricmc.loader.api.FabricLoader;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public class ModChecker implements IModChecker
|
||||
{
|
||||
public static final ModChecker INSTANCE = new ModChecker();
|
||||
@@ -32,4 +34,10 @@ public class ModChecker implements IModChecker
|
||||
return FabricLoader.getInstance().isModLoaded(modid);
|
||||
}
|
||||
|
||||
@Override
|
||||
public File modLocation(String modid)
|
||||
{
|
||||
return new File(FabricLoader.getInstance().getModContainer(modid).get().getOrigin().getPaths().get(0).toUri());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+5
-5
@@ -33,7 +33,7 @@ import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.ISodiumAcce
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
|
||||
import me.jellysquid.mods.sodium.client.render.SodiumWorldRenderer;
|
||||
import net.minecraft.client.Minecraft;
|
||||
#if PRE_MC_1_17_1
|
||||
#if MC_VER < MC_1_17_1
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.network.protocol.Packet;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
@@ -60,21 +60,21 @@ public class SodiumAccessor implements ISodiumAccessor
|
||||
return "Sodium-Fabric";
|
||||
}
|
||||
|
||||
#if POST_MC_1_17_1
|
||||
#if MC_VER >= MC_1_17_1
|
||||
@Override
|
||||
public HashSet<DhChunkPos> getNormalRenderedChunks()
|
||||
{
|
||||
SodiumWorldRenderer renderer = SodiumWorldRenderer.instance();
|
||||
LevelHeightAccessor height = Minecraft.getInstance().level;
|
||||
|
||||
#if POST_MC_1_20_1
|
||||
#if MC_VER >= MC_1_20_1
|
||||
// TODO: This is just a tmp solution, use a proper solution later
|
||||
return MC_RENDER.getMaximumRenderedChunks().stream().filter((DhChunkPos chunk) -> {
|
||||
return (renderer.isBoxVisible(
|
||||
chunk.getMinBlockX() + 1, height.getMinBuildHeight() + 1, chunk.getMinBlockZ() + 1,
|
||||
chunk.getMinBlockX() + 15, height.getMaxBuildHeight() - 1, chunk.getMinBlockZ() + 15));
|
||||
}).collect(Collectors.toCollection(HashSet::new));
|
||||
#elif POST_MC_1_18_2
|
||||
#elif MC_VER >= MC_1_18_2
|
||||
// 0b11 = Lighted chunk & loaded chunk
|
||||
return renderer.getChunkTracker().getChunks(0b00).filter(
|
||||
(long l) -> {
|
||||
@@ -134,7 +134,7 @@ public class SodiumAccessor implements ISodiumAccessor
|
||||
@Override
|
||||
public void setFogOcclusion(boolean b)
|
||||
{
|
||||
#if POST_MC_1_20_1
|
||||
#if MC_VER >= MC_1_20_1
|
||||
me.jellysquid.mods.sodium.client.SodiumClientMod.options().performance.useFogOcclusion = b;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -15,7 +15,8 @@
|
||||
"client.MixinFogRenderer",
|
||||
"client.MixinGameRenderer",
|
||||
"client.MixinLevelRenderer",
|
||||
"client.MixinLightmap",
|
||||
"client.MixinDynamicTexture",
|
||||
"client.MixinLightTexture",
|
||||
"client.MixinOptionsScreen",
|
||||
"client.MixinMinecraft",
|
||||
"client.MixinTextureUtil"
|
||||
|
||||
@@ -17,17 +17,17 @@
|
||||
},
|
||||
|
||||
"license": "LGPL-3",
|
||||
"icon": "icon.png",
|
||||
"icon": "assets/distanthorizons/icon.png",
|
||||
|
||||
"accessWidener": "distanthorizons.accesswidener",
|
||||
|
||||
"environment": "*",
|
||||
"entrypoints": {
|
||||
"client": [
|
||||
"com.seibel.distanthorizons.fabric.FabricClientMain"
|
||||
"com.seibel.distanthorizons.fabric.FabricMain"
|
||||
],
|
||||
"server": [
|
||||
"com.seibel.distanthorizons.fabric.FabricDedicatedServerMain"
|
||||
"com.seibel.distanthorizons.fabric.FabricMain"
|
||||
],
|
||||
"modmenu": [
|
||||
"com.seibel.distanthorizons.fabric.wrappers.config.ModMenuIntegration"
|
||||
|
||||
+63
-72
@@ -1,77 +1,24 @@
|
||||
plugins {
|
||||
id "architectury-plugin" version "3.4-SNAPSHOT"
|
||||
}
|
||||
unimined.minecraft {
|
||||
minecraftForge {
|
||||
loader forge_version
|
||||
mixinConfig("DistantHorizons.forge.mixins.json")
|
||||
|
||||
sourceCompatibility = targetCompatibility = JavaVersion.VERSION_17
|
||||
|
||||
architectury {
|
||||
platformSetupLoomIde()
|
||||
forge()
|
||||
}
|
||||
|
||||
//loom {
|
||||
// forge {
|
||||
// convertAccessWideners.set(true)
|
||||
// extraAccessWideners.add("lod.accesswidener")
|
||||
// mixinConfigs("DistantHorizons.mixins.json")
|
||||
// }
|
||||
//}
|
||||
|
||||
loom {
|
||||
accessWidenerPath = project(":common").file("src/main/resources/${accessWidenerVersion}.distanthorizons.accesswidener")
|
||||
|
||||
forge {
|
||||
convertAccessWideners = true
|
||||
extraAccessWideners.add loom.accessWidenerPath.get().asFile.name
|
||||
|
||||
mixinConfigs = [
|
||||
"DistantHorizons.mixins.json"
|
||||
]
|
||||
file("build/sourcesSets/main/META-INF/").mkdirs()
|
||||
accessTransformer(aw2at(
|
||||
project(":common").file("src/main/resources/${accessWidenerVersion}.distanthorizons.accesswidener"),
|
||||
file("build/sourcesSets/main/META-INF/accesstransformer.cfg") // We'd wanna output the access transformer to somewhere where it'll only appear in the final jar
|
||||
))
|
||||
}
|
||||
|
||||
// "runs" isn't required, but when we do need it then it can be useful
|
||||
runs {
|
||||
client {
|
||||
client()
|
||||
setConfigName("Forge Client")
|
||||
ideConfigGenerated(true)
|
||||
runDir("../run")
|
||||
vmArgs("-XX:-OmitStackTraceInFastThrow", minecraftMemoryJavaArg)
|
||||
}
|
||||
server {
|
||||
server()
|
||||
setConfigName("Forge Server")
|
||||
ideConfigGenerated(true)
|
||||
runDir("../run")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
remapJar {
|
||||
inputFile = shadowJar.archiveFile
|
||||
dependsOn shadowJar
|
||||
classifier null
|
||||
}
|
||||
|
||||
|
||||
def addMod(path, enabled) {
|
||||
if (enabled == "2")
|
||||
dependencies { implementation(path) }
|
||||
dependencies { modImplementation(path) }
|
||||
else if (enabled == "1")
|
||||
dependencies { modCompileOnly(path) }
|
||||
dependencies { compileOnly(path) }
|
||||
}
|
||||
dependencies {
|
||||
minecraft "com.mojang:minecraft:${rootProject.minecraft_version}"
|
||||
mappings loom.layered() {
|
||||
// Mojmap mappings
|
||||
officialMojangMappings()
|
||||
// Parchment mappings (it adds parameter mappings & javadoc)
|
||||
parchment("org.parchmentmc.data:parchment-${rootProject.parchment_version}@zip")
|
||||
}
|
||||
|
||||
// Forge
|
||||
forge "net.minecraftforge:forge:${rootProject.minecraft_version}-${rootProject.forge_version}"
|
||||
|
||||
// Architectury API
|
||||
// if (minecraft_version == "1.16.5") {
|
||||
// implementation("me.shedaniel:architectury-forge:${rootProject.architectury_version}")
|
||||
@@ -86,28 +33,45 @@ dependencies {
|
||||
addMod("curse.maven:TerraForged-363820:${rootProject.terraforged_version}", rootProject.enable_terraforged)
|
||||
|
||||
addMod("curse.maven:TerraFirmaCraft-302973:4616004", rootProject.enable_terrafirmacraft)
|
||||
|
||||
// annotationProcessor "org.spongepowered:mixin:0.8.5:processor"
|
||||
|
||||
// if (System.getProperty("idea.sync.active") != "true") {
|
||||
// annotationProcessor "org.spongepowered:mixin:0.8.4:processor"
|
||||
// }
|
||||
}
|
||||
|
||||
task deleteResources(type: Delete) {
|
||||
delete file("build/resources/main")
|
||||
}
|
||||
|
||||
tasks.register('copyAllResources') {
|
||||
dependsOn(copyCoreResources)
|
||||
dependsOn(copyCommonLoaderResources)
|
||||
}
|
||||
|
||||
|
||||
|
||||
processResources {
|
||||
dependsOn(tasks.named('copyAllResources'))
|
||||
}
|
||||
|
||||
tasks.named('runClient') {
|
||||
dependsOn(tasks.named('copyAllResources'))
|
||||
finalizedBy(deleteResources)
|
||||
afterEvaluate {
|
||||
runClient {
|
||||
dependsOn(tasks.named('copyAllResources'))
|
||||
}
|
||||
|
||||
// TODO this isn't a great place for these, but `tasks.build.doLast` doesn't always work and I'm not sure of a better place right now
|
||||
tasks.runClient.doFirst {
|
||||
// TODO can we just ignore these folders instead?
|
||||
// deleting them may cause issues if the OS locks the files
|
||||
// and it feels hacky
|
||||
delete file("../common/build/libs")
|
||||
delete file("../coreSubProjects/core/build/libs")
|
||||
delete file("../coreSubProjects/api/build/libs")
|
||||
}
|
||||
}
|
||||
|
||||
remapJar {
|
||||
inputFile = shadowJar.archiveFile
|
||||
dependsOn shadowJar
|
||||
// classifier null
|
||||
}
|
||||
|
||||
|
||||
@@ -121,4 +85,31 @@ sourcesJar {
|
||||
// withVariantsFromConfiguration(project.configurations.shadowRuntimeElements) {
|
||||
// skip()
|
||||
// }
|
||||
//}
|
||||
//}
|
||||
|
||||
|
||||
|
||||
// TODO this was specifically added for MC 1.20.4 and should not be used on MC versions prior to it
|
||||
// source: https://github.com/MinecraftForge/MinecraftForge/blob/5d0047753dfac0caaf5d97cc3f5c9a8b0990cb44/mdk/build.gradle#L209-L217
|
||||
//
|
||||
// Merge the resources and classes into the same directory.
|
||||
// This is done because java expects modules to be in a single directory.
|
||||
// And if we have it in multiple we have to do performance intensive hacks like having the UnionFileSystem
|
||||
// This will eventually be migrated to ForgeGradle so modders don't need to manually do it. But that is later.
|
||||
sourceSets.each {
|
||||
if ( // Only run on MC 1.20.4 or later
|
||||
// FIXME: Add an environment variable for the Major, Minor, and Patch version number of Minecraft
|
||||
minecraft_version.split("\\.")[1].toInteger() >= 20 &&
|
||||
(
|
||||
minecraft_version.split("\\.").length > 1 && // Incase there isn't a minor version
|
||||
minecraft_version.split("\\.")[2].toInteger() >= 4
|
||||
)
|
||||
) {
|
||||
// all of our code and resources should be in the sourceSets/main/ folder for Forge 1.20.4+
|
||||
def dir = layout.buildDirectory.dir("sourcesSets/$it.name")
|
||||
println "source name: [" + it.name + "]"// as of 2024-2-4 "it.name" only returned "main" and "test"
|
||||
it.output.resourcesDir = dir
|
||||
it.java.destinationDirectory = dir
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
package com.seibel.distanthorizons.forge;
|
||||
|
||||
import com.seibel.distanthorizons.common.AbstractModInitializer;
|
||||
import com.seibel.distanthorizons.common.util.ProxyUtil;
|
||||
import com.seibel.distanthorizons.common.wrappers.minecraft.MinecraftRenderWrapper;
|
||||
import com.seibel.distanthorizons.common.wrappers.world.ClientLevelWrapper;
|
||||
@@ -36,7 +37,7 @@ import com.seibel.distanthorizons.coreapi.ModInfo;
|
||||
import net.minecraft.world.level.LevelAccessor;
|
||||
|
||||
import net.minecraft.client.multiplayer.ClientLevel;
|
||||
#if PRE_MC_1_19_2
|
||||
#if MC_VER < MC_1_19_2
|
||||
import net.minecraftforge.event.world.ChunkEvent;
|
||||
import net.minecraftforge.event.world.WorldEvent;
|
||||
#else
|
||||
@@ -44,13 +45,13 @@ import net.minecraftforge.event.level.ChunkEvent;
|
||||
import net.minecraftforge.event.level.LevelEvent;
|
||||
#endif
|
||||
|
||||
#if POST_MC_1_18_2
|
||||
#if MC_VER >= MC_1_18_2
|
||||
import net.minecraftforge.client.event.RenderLevelStageEvent;
|
||||
#endif
|
||||
import net.minecraftforge.event.entity.player.PlayerInteractEvent;
|
||||
import net.minecraft.world.level.chunk.ChunkAccess;
|
||||
|
||||
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
//import net.minecraftforge.network.NetworkRegistry;
|
||||
//import net.minecraftforge.network.simple.SimpleChannel;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
@@ -71,7 +72,7 @@ import org.lwjgl.opengl.GL32;
|
||||
* @author James_Seibel
|
||||
* @version 2023-7-27
|
||||
*/
|
||||
public class ForgeClientProxy
|
||||
public class ForgeClientProxy implements AbstractModInitializer.IEventProxy
|
||||
{
|
||||
private static final IMinecraftClientWrapper MC = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class);
|
||||
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
|
||||
@@ -79,7 +80,7 @@ public class ForgeClientProxy
|
||||
// private static SimpleChannel multiversePluginChannel;
|
||||
|
||||
|
||||
#if PRE_MC_1_19_2
|
||||
#if MC_VER < MC_1_19_2
|
||||
private static LevelAccessor GetEventLevel(WorldEvent e) { return e.getWorld(); }
|
||||
#else
|
||||
private static LevelAccessor GetEventLevel(LevelEvent e) { return e.getLevel(); }
|
||||
@@ -87,6 +88,15 @@ public class ForgeClientProxy
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void registerEvents()
|
||||
{
|
||||
MinecraftForge.EVENT_BUS.register(this);
|
||||
this.setupNetworkingListeners();
|
||||
}
|
||||
|
||||
|
||||
|
||||
//=============//
|
||||
// tick events //
|
||||
//=============//
|
||||
@@ -107,7 +117,7 @@ public class ForgeClientProxy
|
||||
//==============//
|
||||
|
||||
@SubscribeEvent
|
||||
#if PRE_MC_1_19_2
|
||||
#if MC_VER < MC_1_19_2
|
||||
public void clientLevelLoadEvent(WorldEvent.Load event)
|
||||
#else
|
||||
public void clientLevelLoadEvent(LevelEvent.Load event)
|
||||
@@ -115,7 +125,7 @@ public class ForgeClientProxy
|
||||
{
|
||||
LOGGER.info("level load");
|
||||
|
||||
#if PRE_MC_1_19_2
|
||||
#if MC_VER < MC_1_19_2
|
||||
LevelAccessor level = event.getWorld();
|
||||
#else
|
||||
LevelAccessor level = event.getLevel();
|
||||
@@ -131,7 +141,7 @@ public class ForgeClientProxy
|
||||
ClientApi.INSTANCE.clientLevelLoadEvent(clientLevelWrapper);
|
||||
}
|
||||
@SubscribeEvent
|
||||
#if PRE_MC_1_19_2
|
||||
#if MC_VER < MC_1_19_2
|
||||
public void clientLevelUnloadEvent(WorldEvent.Unload event)
|
||||
#else
|
||||
public void clientLevelUnloadEvent(LevelEvent.Load event)
|
||||
@@ -139,7 +149,7 @@ public class ForgeClientProxy
|
||||
{
|
||||
LOGGER.info("level unload");
|
||||
|
||||
#if PRE_MC_1_19_2
|
||||
#if MC_VER < MC_1_19_2
|
||||
LevelAccessor level = event.getWorld();
|
||||
#else
|
||||
LevelAccessor level = event.getLevel();
|
||||
@@ -163,9 +173,14 @@ public class ForgeClientProxy
|
||||
@SubscribeEvent
|
||||
public void rightClickBlockEvent(PlayerInteractEvent.RightClickBlock event)
|
||||
{
|
||||
if (SharedApi.isChunkAtBlockPosAlreadyUpdating(event.getPos().getX(), event.getPos().getZ()))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
LOGGER.trace("interact or block place event at blockPos: " + event.getPos());
|
||||
|
||||
#if PRE_MC_1_19_2
|
||||
#if MC_VER < MC_1_19_2
|
||||
LevelAccessor level = event.getWorld();
|
||||
#else
|
||||
LevelAccessor level = event.getLevel();
|
||||
@@ -177,9 +192,14 @@ public class ForgeClientProxy
|
||||
@SubscribeEvent
|
||||
public void leftClickBlockEvent(PlayerInteractEvent.LeftClickBlock event)
|
||||
{
|
||||
if (SharedApi.isChunkAtBlockPosAlreadyUpdating(event.getPos().getX(), event.getPos().getZ()))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
LOGGER.trace("break or block attack at blockPos: " + event.getPos());
|
||||
|
||||
#if PRE_MC_1_19_2
|
||||
#if MC_VER < MC_1_19_2
|
||||
LevelAccessor level = event.getWorld();
|
||||
#else
|
||||
LevelAccessor level = event.getLevel();
|
||||
@@ -217,7 +237,7 @@ public class ForgeClientProxy
|
||||
//==============//
|
||||
|
||||
@SubscribeEvent
|
||||
public void registerKeyBindings(#if PRE_MC_1_19_2 InputEvent.KeyInputEvent #else InputEvent.Key #endif event)
|
||||
public void registerKeyBindings(#if MC_VER < MC_1_19_2 InputEvent.KeyInputEvent #else InputEvent.Key #endif event)
|
||||
{
|
||||
if (Minecraft.getInstance().player == null)
|
||||
{
|
||||
@@ -237,8 +257,7 @@ public class ForgeClientProxy
|
||||
// networking //
|
||||
//============//
|
||||
|
||||
/** @param event this is just to ensure the event is called at the right time, if it is called outside the {@link FMLClientSetupEvent} event, the binding may fail */
|
||||
public static void setupNetworkingListeners(FMLClientSetupEvent event)
|
||||
public void setupNetworkingListeners()
|
||||
{
|
||||
// multiversePluginChannel = NetworkRegistry.newSimpleChannel(
|
||||
// new ResourceLocation(ModInfo.NETWORKING_RESOURCE_NAMESPACE, ModInfo.MULTIVERSE_PLUGIN_NAMESPACE),
|
||||
@@ -298,15 +317,15 @@ public class ForgeClientProxy
|
||||
//===========//
|
||||
|
||||
@SubscribeEvent
|
||||
#if POST_MC_1_18_2
|
||||
#if MC_VER >= MC_1_18_2
|
||||
public void afterLevelRenderEvent(RenderLevelStageEvent event)
|
||||
#else
|
||||
public void afterLevelRenderEvent(TickEvent.RenderTickEvent event)
|
||||
#endif
|
||||
{
|
||||
#if POST_MC_1_20_1
|
||||
#if MC_VER >= MC_1_20_1
|
||||
if (event.getStage() == RenderLevelStageEvent.Stage.AFTER_LEVEL)
|
||||
#elif POST_MC_1_18_2
|
||||
#elif MC_VER >= MC_1_18_2
|
||||
if (event.getStage() == RenderLevelStageEvent.Stage.AFTER_SOLID_BLOCKS)
|
||||
#else
|
||||
// FIXME: Is this the correct location for 1.16 & 1.17???
|
||||
|
||||
@@ -19,184 +19,115 @@
|
||||
|
||||
package com.seibel.distanthorizons.forge;
|
||||
|
||||
import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiAfterDhInitEvent;
|
||||
import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiBeforeDhInitEvent;
|
||||
import com.seibel.distanthorizons.common.LodCommonMain;
|
||||
import com.seibel.distanthorizons.common.forge.LodForgeMethodCaller;
|
||||
import com.seibel.distanthorizons.common.wrappers.DependencySetup;
|
||||
import com.mojang.brigadier.CommandDispatcher;
|
||||
import com.seibel.distanthorizons.common.AbstractModInitializer;
|
||||
import com.seibel.distanthorizons.common.wrappers.gui.GetConfigScreen;
|
||||
import com.seibel.distanthorizons.common.wrappers.minecraft.MinecraftClientWrapper;
|
||||
import com.seibel.distanthorizons.core.jar.ModJarInfo;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.AbstractOptifineAccessor;
|
||||
import com.seibel.distanthorizons.coreapi.DependencyInjection.ApiEventInjector;
|
||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IModChecker;
|
||||
import com.seibel.distanthorizons.coreapi.ModInfo;
|
||||
import com.seibel.distanthorizons.core.dependencyInjection.ModAccessorInjector;
|
||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IOptifineAccessor;
|
||||
import com.seibel.distanthorizons.forge.wrappers.ForgeDependencySetup;
|
||||
|
||||
import com.seibel.distanthorizons.forge.wrappers.modAccessor.ModChecker;
|
||||
import com.seibel.distanthorizons.forge.wrappers.modAccessor.OptifineAccessor;
|
||||
|
||||
import net.minecraft.client.renderer.block.model.BakedQuad;
|
||||
import net.minecraft.core.Direction;
|
||||
#if POST_MC_1_19_2
|
||||
import net.minecraft.util.RandomSource;
|
||||
#endif
|
||||
import net.minecraft.world.level.ColorResolver;
|
||||
import net.minecraft.world.level.biome.Biome;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.commands.CommandSourceStack;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.event.RegisterCommandsEvent;
|
||||
import net.minecraftforge.fml.ModLoadingContext;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
import net.minecraftforge.fml.event.lifecycle.*;
|
||||
#if MC_VER == MC_1_16_5
|
||||
import net.minecraftforge.fml.event.server.FMLServerStartingEvent;
|
||||
#elif MC_VER == MC_1_17_1
|
||||
import net.minecraftforge.fmlserverevents.FMLServerStartingEvent;
|
||||
#else
|
||||
import net.minecraftforge.event.server.ServerStartingEvent;
|
||||
#endif
|
||||
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
|
||||
#if PRE_MC_1_17_1
|
||||
#if MC_VER < MC_1_17_1
|
||||
import net.minecraftforge.fml.ExtensionPoint;
|
||||
#elif MC_1_17_1
|
||||
#elif MC_VER == MC_1_17_1
|
||||
import net.minecraftforge.fmlclient.ConfigGuiHandler;
|
||||
#elif POST_MC_1_18_2 && PRE_MC_1_19_2
|
||||
#elif MC_VER >= MC_1_18_2 && MC_VER < MC_1_19_2
|
||||
import net.minecraftforge.client.ConfigGuiHandler;
|
||||
#else
|
||||
import net.minecraftforge.client.ConfigScreenHandler;
|
||||
#endif
|
||||
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
// these imports change due to forge refactoring classes in 1.19
|
||||
#if PRE_MC_1_19_2
|
||||
#if MC_VER < MC_1_19_2
|
||||
import net.minecraftforge.client.model.data.ModelDataMap;
|
||||
|
||||
import java.util.Random;
|
||||
#else
|
||||
import net.minecraft.client.renderer.RenderType;
|
||||
import net.minecraftforge.client.model.data.ModelData;
|
||||
#endif
|
||||
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* Initialize and setup the Mod. <br>
|
||||
* If you are looking for the real start of the mod
|
||||
* check out the ClientProxy.
|
||||
*
|
||||
* @author coolGi
|
||||
* @author Ran
|
||||
* @author James Seibel
|
||||
* @version 8-15-2022
|
||||
*/
|
||||
@Mod(ModInfo.ID)
|
||||
public class ForgeMain implements LodForgeMethodCaller
|
||||
@Mod("distanthorizons") // TODO: Change it back to ModInfo.ID when forge works
|
||||
public class ForgeMain extends AbstractModInitializer
|
||||
{
|
||||
private static final Logger LOGGER = DhLoggerBuilder.getLogger(MethodHandles.lookup().lookupClass().getSimpleName());
|
||||
public static ForgeClientProxy client_proxy = null;
|
||||
public static ForgeServerProxy server_proxy = null;
|
||||
|
||||
public ForgeMain()
|
||||
{
|
||||
DependencySetup.createClientBindings();
|
||||
|
||||
// initDedicated(null);
|
||||
// initDedicated(null);
|
||||
// Register the mod initializer (Actual event registration is done in the different proxies)
|
||||
FMLJavaModLoadingContext.get().getModEventBus().addListener(this::initClient);
|
||||
FMLJavaModLoadingContext.get().getModEventBus().addListener(this::initDedicated);
|
||||
FMLJavaModLoadingContext.get().getModEventBus().addListener((FMLClientSetupEvent e) -> this.onInitializeClient());
|
||||
FMLJavaModLoadingContext.get().getModEventBus().addListener((FMLDedicatedServerSetupEvent e) -> this.onInitializeServer());
|
||||
}
|
||||
|
||||
private void initClient(final FMLClientSetupEvent event)
|
||||
@Override
|
||||
protected void createInitialBindings() { SingletonInjector.INSTANCE.bind(IModChecker.class, ModChecker.INSTANCE); }
|
||||
|
||||
@Override
|
||||
protected IEventProxy createClientProxy() { return new ForgeClientProxy(); }
|
||||
|
||||
@Override
|
||||
protected IEventProxy createServerProxy(boolean isDedicated) { return new ForgeServerProxy(isDedicated); }
|
||||
|
||||
@Override
|
||||
protected void initializeModCompat()
|
||||
{
|
||||
ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeDhInitEvent.class, null);
|
||||
this.tryCreateModCompatAccessor("optifine", IOptifineAccessor.class, OptifineAccessor::new);
|
||||
|
||||
LOGGER.info("Initializing Mod");
|
||||
LodCommonMain.startup(this);
|
||||
ForgeDependencySetup.createInitialBindings();
|
||||
LOGGER.info(ModInfo.READABLE_NAME + ", Version: " + ModInfo.VERSION);
|
||||
|
||||
// Print git info (Useful for dev builds)
|
||||
LOGGER.info("DH Branch: " + ModJarInfo.Git_Branch);
|
||||
LOGGER.info("DH Commit: " + ModJarInfo.Git_Commit);
|
||||
LOGGER.info("DH Jar Build Source: " + ModJarInfo.Build_Source);
|
||||
|
||||
client_proxy = new ForgeClientProxy();
|
||||
MinecraftForge.EVENT_BUS.register(client_proxy);
|
||||
server_proxy = new ForgeServerProxy(false);
|
||||
MinecraftForge.EVENT_BUS.register(server_proxy);
|
||||
|
||||
if (AbstractOptifineAccessor.optifinePresent())
|
||||
{
|
||||
ModAccessorInjector.INSTANCE.bind(IOptifineAccessor.class, new OptifineAccessor());
|
||||
}
|
||||
|
||||
#if PRE_MC_1_17_1
|
||||
#if MC_VER < MC_1_17_1
|
||||
ModLoadingContext.get().registerExtensionPoint(ExtensionPoint.CONFIGGUIFACTORY,
|
||||
() -> (client, parent) -> GetConfigScreen.getScreen(parent));
|
||||
#elif MC_1_17_1 || MC_1_18_2 || PRE_MC_1_19_2
|
||||
#elif MC_VER >= MC_1_17_1 && MC_VER < MC_1_19_2
|
||||
ModLoadingContext.get().registerExtensionPoint(ConfigGuiHandler.ConfigGuiFactory.class,
|
||||
() -> new ConfigGuiHandler.ConfigGuiFactory((client, parent) -> GetConfigScreen.getScreen(parent)));
|
||||
#else
|
||||
ModLoadingContext.get().registerExtensionPoint(ConfigScreenHandler.ConfigScreenFactory.class,
|
||||
() -> new ConfigScreenHandler.ConfigScreenFactory((client, parent) -> GetConfigScreen.getScreen(parent)));
|
||||
#endif
|
||||
|
||||
ForgeClientProxy.setupNetworkingListeners(event);
|
||||
|
||||
LOGGER.info(ModInfo.READABLE_NAME + " Initialized");
|
||||
|
||||
ApiEventInjector.INSTANCE.fireAllEvents(DhApiAfterDhInitEvent.class, null);
|
||||
|
||||
// Init config
|
||||
// The reason im initialising in this rather than the post init process is cus im using this for the auto updater
|
||||
LodCommonMain.initConfig();
|
||||
}
|
||||
|
||||
private void initDedicated(final FMLDedicatedServerSetupEvent event)
|
||||
{
|
||||
// DependencySetup.createServerBindings();
|
||||
// initCommon();
|
||||
|
||||
// server_proxy = new ForgeServerProxy(true);
|
||||
// MinecraftForge.EVENT_BUS.register(server_proxy);
|
||||
//
|
||||
postInitCommon();
|
||||
}
|
||||
|
||||
private void postInitCommon()
|
||||
{
|
||||
LOGGER.info("Post-Initializing Mod");
|
||||
ForgeDependencySetup.runDelayedSetup();
|
||||
|
||||
LOGGER.info("Mod Post-Initialized");
|
||||
}
|
||||
|
||||
#if PRE_MC_1_19_2
|
||||
private final ModelDataMap modelData = new ModelDataMap.Builder().build();
|
||||
#else
|
||||
private final ModelData modelData = ModelData.EMPTY;
|
||||
#endif
|
||||
|
||||
@Override
|
||||
#if PRE_MC_1_19_2
|
||||
public List<BakedQuad> getQuads(MinecraftClientWrapper mc, Block block, BlockState blockState, Direction direction, Random random)
|
||||
protected void subscribeRegisterCommandsEvent(Consumer<CommandDispatcher<CommandSourceStack>> eventHandler)
|
||||
{
|
||||
return mc.getModelManager().getBlockModelShaper().getBlockModel(block.defaultBlockState()).getQuads(blockState, direction, random, modelData);
|
||||
MinecraftForge.EVENT_BUS.addListener((RegisterCommandsEvent e) -> { eventHandler.accept(e.getDispatcher()); });
|
||||
}
|
||||
#else
|
||||
public List<BakedQuad> getQuads(MinecraftClientWrapper mc, Block block, BlockState blockState, Direction direction, RandomSource random)
|
||||
{
|
||||
return mc.getModelManager().getBlockModelShaper().getBlockModel(block.defaultBlockState()).getQuads(blockState, direction, random, modelData #if POST_MC_1_19_2 , RenderType.solid() #endif );
|
||||
}
|
||||
#endif
|
||||
|
||||
@Override //TODO: Check this if its still needed
|
||||
public int colorResolverGetColor(ColorResolver resolver, Biome biome, double x, double z)
|
||||
@Override
|
||||
protected void subscribeClientStartedEvent(Runnable eventHandler)
|
||||
{
|
||||
#if MC_1_17_1______Still_needed
|
||||
return resolver.m_130045_(biome, x, z);
|
||||
#else
|
||||
return resolver.getColor(biome, x, z);
|
||||
#endif
|
||||
|
||||
// FIXME What event is this?
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void subscribeServerStartingEvent(Consumer<MinecraftServer> eventHandler)
|
||||
{
|
||||
MinecraftForge.EVENT_BUS.addListener((#if MC_VER >= MC_1_18_2 ServerStartingEvent #else FMLServerStartingEvent #endif e) ->
|
||||
{
|
||||
eventHandler.accept(e.getServer());
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void runDelayedSetup() { SingletonInjector.INSTANCE.runDelayedSetup(); }
|
||||
|
||||
}
|
||||
|
||||
@@ -1,20 +1,19 @@
|
||||
package com.seibel.distanthorizons.forge;
|
||||
|
||||
import com.seibel.distanthorizons.common.AbstractModInitializer;
|
||||
import com.seibel.distanthorizons.common.util.ProxyUtil;
|
||||
import com.seibel.distanthorizons.common.wrappers.chunk.ChunkWrapper;
|
||||
import com.seibel.distanthorizons.common.wrappers.world.ClientLevelWrapper;
|
||||
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.logging.DhLoggerBuilder;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.chunk.IChunkWrapper;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper;
|
||||
import net.minecraft.client.multiplayer.ClientLevel;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.LevelAccessor;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.event.TickEvent;
|
||||
#if PRE_MC_1_19_2
|
||||
#if MC_VER < MC_1_19_2
|
||||
import net.minecraftforge.event.world.ChunkEvent;
|
||||
import net.minecraftforge.event.world.WorldEvent;
|
||||
#else
|
||||
@@ -23,10 +22,10 @@ import net.minecraftforge.event.level.LevelEvent;
|
||||
#endif
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
|
||||
#if MC_1_16_5
|
||||
#if MC_VER == MC_1_16_5
|
||||
import net.minecraftforge.fml.event.server.FMLServerAboutToStartEvent;
|
||||
import net.minecraftforge.fml.event.server.FMLServerStoppingEvent;
|
||||
#elif MC_1_17_1
|
||||
#elif MC_VER == MC_1_17_1
|
||||
import net.minecraftforge.fmlserverevents.FMLServerAboutToStartEvent;
|
||||
import net.minecraftforge.fmlserverevents.FMLServerStoppingEvent;
|
||||
#else
|
||||
@@ -39,9 +38,9 @@ import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class ForgeServerProxy
|
||||
public class ForgeServerProxy implements AbstractModInitializer.IEventProxy
|
||||
{
|
||||
#if PRE_MC_1_19_2
|
||||
#if MC_VER < MC_1_19_2
|
||||
private static LevelAccessor GetEventLevel(WorldEvent e) { return e.getWorld(); }
|
||||
#else
|
||||
private static LevelAccessor GetEventLevel(LevelEvent e) { return e.getLevel(); }
|
||||
@@ -53,6 +52,15 @@ public class ForgeServerProxy
|
||||
public static Supplier<Boolean> isGenerationThreadChecker = null;
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void registerEvents()
|
||||
{
|
||||
MinecraftForge.EVENT_BUS.register(this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//=============//
|
||||
// constructor //
|
||||
//=============//
|
||||
@@ -81,21 +89,21 @@ public class ForgeServerProxy
|
||||
|
||||
// ServerWorldLoadEvent
|
||||
@SubscribeEvent
|
||||
public void dedicatedWorldLoadEvent(#if MC_1_16_5 || MC_1_17_1 FMLServerAboutToStartEvent #else ServerAboutToStartEvent #endif event)
|
||||
public void dedicatedWorldLoadEvent(#if MC_VER == MC_1_16_5 || MC_VER == MC_1_17_1 FMLServerAboutToStartEvent #else ServerAboutToStartEvent #endif event)
|
||||
{
|
||||
this.serverApi.serverLoadEvent(this.isDedicated);
|
||||
}
|
||||
|
||||
// ServerWorldUnloadEvent
|
||||
@SubscribeEvent
|
||||
public void serverWorldUnloadEvent(#if MC_1_16_5 || MC_1_17_1 FMLServerStoppingEvent #else ServerStoppingEvent #endif event)
|
||||
public void serverWorldUnloadEvent(#if MC_VER == MC_1_16_5 || MC_VER == MC_1_17_1 FMLServerStoppingEvent #else ServerStoppingEvent #endif event)
|
||||
{
|
||||
this.serverApi.serverUnloadEvent();
|
||||
}
|
||||
|
||||
// ServerLevelLoadEvent
|
||||
@SubscribeEvent
|
||||
#if PRE_MC_1_19_2
|
||||
#if MC_VER < MC_1_19_2
|
||||
public void serverLevelLoadEvent(WorldEvent.Load event)
|
||||
#else
|
||||
public void serverLevelLoadEvent(LevelEvent.Load event)
|
||||
@@ -109,7 +117,7 @@ public class ForgeServerProxy
|
||||
|
||||
// ServerLevelUnloadEvent
|
||||
@SubscribeEvent
|
||||
#if PRE_MC_1_19_2
|
||||
#if MC_VER < MC_1_19_2
|
||||
public void serverLevelUnloadEvent(WorldEvent.Unload event)
|
||||
#else
|
||||
public void serverLevelUnloadEvent(LevelEvent.Unload event)
|
||||
|
||||
@@ -14,10 +14,24 @@ import java.util.Set;
|
||||
*/
|
||||
public class ForgeMixinPlugin implements IMixinConfigPlugin
|
||||
{
|
||||
private boolean firstRun = false;
|
||||
private boolean isForgeMixinFile;
|
||||
|
||||
|
||||
@Override
|
||||
public boolean shouldApplyMixin(String targetClassName, String mixinClassName)
|
||||
{
|
||||
if (!this.firstRun) {
|
||||
try {
|
||||
Class<?> cls = Class.forName("net.neoforged.fml.common.Mod"); // Check if a NeoForge exclusive class exists
|
||||
this.isForgeMixinFile = false;
|
||||
} catch (ClassNotFoundException e) {
|
||||
this.isForgeMixinFile = true;
|
||||
}
|
||||
}
|
||||
if (!this.isForgeMixinFile)
|
||||
return false;
|
||||
|
||||
if (mixinClassName.contains(".mods."))
|
||||
{ // If the mixin wants to go into a mod then we check if that mod is loaded or not
|
||||
return ModList.get().isLoaded(
|
||||
@@ -28,44 +42,27 @@ public class ForgeMixinPlugin implements IMixinConfigPlugin
|
||||
.replaceAll("\\..*$", "") // Replaces everything after the mod name
|
||||
);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onLoad(String mixinPackage)
|
||||
{
|
||||
|
||||
}
|
||||
public void onLoad(String mixinPackage) { }
|
||||
|
||||
@Override
|
||||
public String getRefMapperConfig()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
public String getRefMapperConfig() { return null; }
|
||||
|
||||
@Override
|
||||
public void acceptTargets(Set<String> myTargets, Set<String> otherTargets)
|
||||
{
|
||||
|
||||
}
|
||||
public void acceptTargets(Set<String> myTargets, Set<String> otherTargets) { }
|
||||
|
||||
@Override
|
||||
public List<String> getMixins()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
public List<String> getMixins() { return null; }
|
||||
|
||||
@Override
|
||||
public void preApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo)
|
||||
{
|
||||
|
||||
}
|
||||
public void preApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) { }
|
||||
|
||||
@Override
|
||||
public void postApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo)
|
||||
{
|
||||
|
||||
}
|
||||
public void postApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) { }
|
||||
|
||||
}
|
||||
+1
-1
@@ -16,7 +16,7 @@ public class MixinClientPacketListener
|
||||
@Inject(method = "handleLogin", at = @At("RETURN"))
|
||||
void onHandleLoginEnd(CallbackInfo ci) { ClientApi.INSTANCE.onClientOnlyConnected(); }
|
||||
|
||||
#if PRE_MC_1_19_4
|
||||
#if MC_VER < MC_1_19_4
|
||||
@Inject(method = "cleanup", at = @At("HEAD"))
|
||||
#else
|
||||
@Inject(method = "close", at = @At("HEAD"))
|
||||
|
||||
+41
-9
@@ -1,42 +1,74 @@
|
||||
/*
|
||||
* This file is part of the Distant Horizons mod
|
||||
* licensed under the GNU LGPL v3 License.
|
||||
*
|
||||
* Copyright (C) 2020-2023 James Seibel
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.seibel.distanthorizons.forge.mixins.client;
|
||||
|
||||
|
||||
import com.mojang.blaze3d.platform.NativeImage;
|
||||
|
||||
import com.seibel.distanthorizons.common.wrappers.minecraft.MinecraftRenderWrapper;
|
||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper;
|
||||
import net.minecraft.client.renderer.LightTexture;
|
||||
import com.seibel.distanthorizons.common.util.ILightTextureMarker;
|
||||
|
||||
import net.minecraft.client.renderer.texture.DynamicTexture;
|
||||
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
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.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@Mixin(DynamicTexture.class)
|
||||
public class MixinLightmap
|
||||
public abstract class MixinDynamicTexture implements ILightTextureMarker
|
||||
{
|
||||
/** Used to prevent accidentally using other dynamic textures as a lightmap */
|
||||
@Unique
|
||||
private boolean isLightTexture = false;
|
||||
|
||||
@Shadow
|
||||
@Final
|
||||
private NativeImage pixels;
|
||||
|
||||
@Inject(method = "Lnet/minecraft/client/renderer/texture/DynamicTexture;upload()V", at = @At("HEAD"), cancellable = true)
|
||||
@Inject(method = "upload()V", at = @At("HEAD"))
|
||||
public void updateLightTexture(CallbackInfo ci)
|
||||
{
|
||||
// since the light map is always updated on the client render thread we should be able to access the client level at the same time
|
||||
IMinecraftClientWrapper mc = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class);
|
||||
if (
|
||||
mc == null ||
|
||||
mc.getWrappedClientLevel() == null
|
||||
)
|
||||
if (!this.isLightTexture
|
||||
|| mc == null
|
||||
|| mc.getWrappedClientLevel() == null
|
||||
)
|
||||
{
|
||||
return;
|
||||
IClientLevelWrapper clientLevel = mc.getWrappedClientLevel();
|
||||
}
|
||||
|
||||
//ApiShared.LOGGER.info("Lightmap update");
|
||||
IClientLevelWrapper clientLevel = mc.getWrappedClientLevel();
|
||||
MinecraftRenderWrapper.INSTANCE.updateLightmap(this.pixels, clientLevel);
|
||||
}
|
||||
|
||||
public void markLightTexture() { this.isLightTexture = true; }
|
||||
|
||||
}
|
||||
+4
-4
@@ -35,7 +35,7 @@ import net.minecraft.client.renderer.FogRenderer.FogMode;
|
||||
import net.minecraft.world.effect.MobEffects;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
#if PRE_MC_1_17_1
|
||||
#if MC_VER < MC_1_17_1
|
||||
import net.minecraft.world.level.material.FluidState;
|
||||
#else
|
||||
import net.minecraft.world.level.material.FogType;
|
||||
@@ -53,10 +53,10 @@ public class MixinFogRenderer
|
||||
|
||||
@Inject(at = @At("RETURN"),
|
||||
method = "setupFog(Lnet/minecraft/client/Camera;Lnet/minecraft/client/renderer/FogRenderer$FogMode;FZF)V",
|
||||
remap = #if MC_1_17_1 || MC_1_18_2 false #else true #endif ) // Remap messiness due to this being weird in forge
|
||||
remap = #if MC_VER == MC_1_17_1 || MC_VER == MC_1_18_2 false #else true #endif ) // Remap messiness due to this being weird in forge
|
||||
private static void disableSetupFog(Camera camera, FogMode fogMode, float f, boolean bl, float partTick, CallbackInfo callback)
|
||||
{
|
||||
#if PRE_MC_1_17_1
|
||||
#if MC_VER < MC_1_17_1
|
||||
FluidState fluidState = camera.getFluidInCamera();
|
||||
boolean cameraNotInFluid = fluidState.isEmpty();
|
||||
#else
|
||||
@@ -71,7 +71,7 @@ public class MixinFogRenderer
|
||||
&& !SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class).isFogStateSpecial()
|
||||
&& Config.Client.Advanced.Graphics.Fog.disableVanillaFog.get())
|
||||
{
|
||||
#if PRE_MC_1_17_1
|
||||
#if MC_VER < MC_1_17_1
|
||||
RenderSystem.fogStart(A_REALLY_REALLY_BIG_VALUE);
|
||||
RenderSystem.fogEnd(A_EVEN_LARGER_VALUE);
|
||||
#else
|
||||
|
||||
+1
-1
@@ -16,7 +16,7 @@ public class MixinGameRenderer
|
||||
{
|
||||
private static final Logger LOGGER = LogManager.getLogger(MixinGameRenderer.class.getSimpleName());
|
||||
|
||||
#if POST_MC_1_17_1
|
||||
#if MC_VER >= MC_1_17_1
|
||||
// FIXME: This I think will dup multiple renderStartupEvent calls...
|
||||
@Inject(method = {"reloadShaders", "preloadUiShader"}, at = @At("TAIL"))
|
||||
public void onStartupShaders(CallbackInfo ci)
|
||||
|
||||
+22
-20
@@ -20,10 +20,11 @@
|
||||
package com.seibel.distanthorizons.forge.mixins.client;
|
||||
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
#if PRE_MC_1_19_4
|
||||
#if MC_VER < MC_1_19_4
|
||||
import com.mojang.math.Matrix4f;
|
||||
#else
|
||||
import net.minecraft.client.Camera;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.GameRenderer;
|
||||
import net.minecraft.client.renderer.LightTexture;
|
||||
import org.joml.Matrix4f;
|
||||
@@ -36,39 +37,34 @@ import com.seibel.distanthorizons.core.config.Config;
|
||||
import com.seibel.distanthorizons.core.api.internal.ClientApi;
|
||||
import com.seibel.distanthorizons.coreapi.util.math.Mat4f;
|
||||
import net.minecraft.client.Camera;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.multiplayer.ClientLevel;
|
||||
import net.minecraft.client.renderer.GameRenderer;
|
||||
import net.minecraft.client.renderer.LevelRenderer;
|
||||
import net.minecraft.client.renderer.LightTexture;
|
||||
import net.minecraft.client.renderer.RenderType;
|
||||
import net.minecraft.world.level.lighting.LevelLightEngine;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
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.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
import java.nio.FloatBuffer;
|
||||
|
||||
#if PRE_MC_1_17_1
|
||||
#if MC_VER < MC_1_17_1
|
||||
import org.lwjgl.opengl.GL15;
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* This class is used to mix in my rendering code
|
||||
* This class is used to mix in DH's 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. <br><br>
|
||||
*
|
||||
* This is also the mixin for rendering the clouds
|
||||
*
|
||||
* @author coolGi
|
||||
* @author James Seibel
|
||||
* @version 12-31-2021
|
||||
*/
|
||||
@Mixin(LevelRenderer.class)
|
||||
public class MixinLevelRenderer
|
||||
@@ -84,7 +80,7 @@ public class MixinLevelRenderer
|
||||
throw new NullPointerException("Null cannot be cast to non-null type.");
|
||||
}
|
||||
|
||||
#if PRE_MC_1_17_1
|
||||
#if MC_VER < MC_1_17_1
|
||||
@Inject(at = @At("RETURN"), method = "renderSky(Lcom/mojang/blaze3d/vertex/PoseStack;F)V")
|
||||
private void renderSky(PoseStack matrixStackIn, float partialTicks, CallbackInfo callback)
|
||||
#else
|
||||
@@ -92,24 +88,26 @@ public class MixinLevelRenderer
|
||||
public void renderClouds(PoseStack poseStack, Matrix4f projectionMatrix, float partialTicks, double cameraX, double cameraY, double cameraZ, CallbackInfo ci)
|
||||
#endif
|
||||
{
|
||||
// FIXME this is only called when clouds are enabled and vanilla render distance is far enough
|
||||
// not having the parital ticks doesn't appear to be critical currently, but might cause weird issues down the line
|
||||
|
||||
// get the partial ticks since renderBlockLayer doesn't
|
||||
// have access to them
|
||||
previousPartialTicks = partialTicks;
|
||||
}
|
||||
|
||||
|
||||
// TODO: Can we move this to forge's client proxy similarly to how fabric does it
|
||||
#if PRE_MC_1_17_1
|
||||
#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",
|
||||
cancellable = true)
|
||||
private void renderChunkLayer(RenderType renderType, PoseStack matrixStackIn, double xIn, double yIn, double zIn, CallbackInfo callback)
|
||||
#elif PRE_MC_1_19_4
|
||||
#elif MC_VER < MC_1_19_4
|
||||
@Inject(at = @At("HEAD"),
|
||||
method = "renderChunkLayer(Lnet/minecraft/client/renderer/RenderType;Lcom/mojang/blaze3d/vertex/PoseStack;DDDLcom/mojang/math/Matrix4f;)V",
|
||||
cancellable = true)
|
||||
private void renderChunkLayer(RenderType renderType, PoseStack modelViewMatrixStack, double cameraXBlockPos, double cameraYBlockPos, double cameraZBlockPos, Matrix4f projectionMatrix, CallbackInfo callback)
|
||||
#elif PRE_MC_1_20_2
|
||||
#elif MC_VER < MC_1_20_2
|
||||
@Inject(at = @At("HEAD"),
|
||||
method = "renderChunkLayer(Lnet/minecraft/client/renderer/RenderType;Lcom/mojang/blaze3d/vertex/PoseStack;DDDLorg/joml/Matrix4f;)V",
|
||||
cancellable = true)
|
||||
@@ -122,7 +120,7 @@ public class MixinLevelRenderer
|
||||
#endif
|
||||
{
|
||||
// get MC's model view and projection matrices
|
||||
#if MC_1_16_5
|
||||
#if MC_VER == MC_1_16_5
|
||||
// get the matrices from the OpenGL fixed pipeline
|
||||
float[] mcProjMatrixRaw = new float[16];
|
||||
GL15.glGetFloatv(GL15.GL_PROJECTION_MATRIX, mcProjMatrixRaw);
|
||||
@@ -142,21 +140,25 @@ public class MixinLevelRenderer
|
||||
// only render before solid blocks
|
||||
if (renderType.equals(RenderType.solid()))
|
||||
{
|
||||
ClientApi.INSTANCE.renderLods(ClientLevelWrapper.getWrapper(level), mcModelViewMatrix, mcProjectionMatrix, previousPartialTicks);
|
||||
ClientApi.INSTANCE.renderLods(ClientLevelWrapper.getWrapper(this.level), mcModelViewMatrix, mcProjectionMatrix, Minecraft.getInstance().getFrameTime());
|
||||
|
||||
// experimental proof-of-concept option
|
||||
if (Config.Client.Advanced.Graphics.AdvancedGraphics.seamlessOverdraw.get())
|
||||
{
|
||||
float[] matrixFloatArray = SeamlessOverdraw.overwriteMinecraftNearFarClipPlanes(mcProjectionMatrix, previousPartialTicks);
|
||||
|
||||
#if MC_1_16_5
|
||||
#if MC_VER == MC_1_16_5
|
||||
SeamlessOverdraw.applyLegacyProjectionMatrix(matrixFloatArray);
|
||||
#elif PRE_MC_1_19_4
|
||||
#elif MC_VER < MC_1_19_4
|
||||
projectionMatrix.load(FloatBuffer.wrap(matrixFloatArray));
|
||||
#else
|
||||
projectionMatrix.set(matrixFloatArray);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else if (renderType.equals(RenderType.translucent()))
|
||||
{
|
||||
ClientApi.INSTANCE.renderDeferredLods(ClientLevelWrapper.getWrapper(this.level), mcModelViewMatrix, mcProjectionMatrix, Minecraft.getInstance().getFrameTime());
|
||||
}
|
||||
|
||||
if (Config.Client.Advanced.Debugging.lodOnlyMode.get())
|
||||
@@ -165,10 +167,10 @@ public class MixinLevelRenderer
|
||||
}
|
||||
}
|
||||
|
||||
#if PRE_MC_1_19_4
|
||||
#if MC_VER < MC_1_19_4
|
||||
@Inject(at = @At(value = "TAIL", target = "Lnet/minecraft/world/level/lighting/LevelLightEngine;runUpdates(IZZ)I"), method = "renderLevel")
|
||||
public void callAfterRunUpdates(PoseStack poseStack, float partialTick, long finishNanoTime, boolean renderBlockOutline, Camera camera, GameRenderer gameRenderer, LightTexture lightTexture, Matrix4f projectionMatrix, CallbackInfo ci)
|
||||
#elif PRE_MC_1_20_1
|
||||
#elif MC_VER < MC_1_20_1
|
||||
@Inject(at = @At(value = "TAIL", target = "Lnet/minecraft/world/level/lighting/LevelLightEngine;runUpdates(IZZ)I"), method = "renderLevel")
|
||||
public void callAfterRunUpdates(PoseStack poseStack, float partialTick, long finishNanoTime, boolean renderBlockOutline, Camera camera, GameRenderer gameRenderer, LightTexture lightTexture, Matrix4f projectionMatrix, CallbackInfo ci)
|
||||
#else
|
||||
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* This file is part of the Distant Horizons mod
|
||||
* licensed under the GNU LGPL v3 License.
|
||||
*
|
||||
* Copyright (C) 2020-2023 James Seibel
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.seibel.distanthorizons.forge.mixins.client;
|
||||
|
||||
|
||||
import com.seibel.distanthorizons.common.util.ILightTextureMarker;
|
||||
|
||||
import net.minecraft.client.renderer.LightTexture;
|
||||
import net.minecraft.client.renderer.texture.DynamicTexture;
|
||||
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
@Mixin(LightTexture.class)
|
||||
public class MixinLightTexture
|
||||
{
|
||||
@Shadow
|
||||
@Final
|
||||
private DynamicTexture lightTexture;
|
||||
|
||||
@Inject(method = "<init>", at = @At("RETURN"))
|
||||
public void markLightTexture(CallbackInfo ci) { ((ILightTextureMarker) this.lightTexture).markLightTexture(); }
|
||||
|
||||
}
|
||||
+3
-3
@@ -25,8 +25,8 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
@Mixin(Minecraft.class)
|
||||
public class MixinMinecraft
|
||||
{
|
||||
#if PRE_MC_1_20_2
|
||||
#if MC_1_20_1
|
||||
#if MC_VER < MC_1_20_2
|
||||
#if MC_VER == MC_1_20_1
|
||||
@Redirect(
|
||||
method = "Lnet/minecraft/client/Minecraft;setInitialScreen(Lcom/mojang/realmsclient/client/RealmsClient;Lnet/minecraft/server/packs/resources/ReloadInstance;Lnet/minecraft/client/main/GameConfig$QuickPlayData;)V",
|
||||
at = @At(value = "INVOKE", target = "Lnet/minecraft/client/Minecraft;setScreen(Lnet/minecraft/client/gui/screens/Screen;)V")
|
||||
@@ -61,7 +61,7 @@ public class MixinMinecraft
|
||||
}
|
||||
#endif
|
||||
|
||||
#if POST_MC_1_20_2
|
||||
#if MC_VER >= MC_1_20_2
|
||||
@Redirect(
|
||||
method = "Lnet/minecraft/client/Minecraft;onGameLoadFinished(Lnet/minecraft/client/Minecraft$GameLoadCookie;)V",
|
||||
at = @At(value = "INVOKE", target = "Ljava/lang/Runnable;run()V")
|
||||
|
||||
+3
-3
@@ -26,7 +26,7 @@ import com.seibel.distanthorizons.core.config.Config;
|
||||
import net.minecraft.client.gui.screens.OptionsScreen;
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
import net.minecraft.network.chat.Component;
|
||||
#if PRE_MC_1_19_2
|
||||
#if MC_VER < MC_1_19_2
|
||||
import net.minecraft.network.chat.TranslatableComponent;
|
||||
#endif
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
@@ -57,7 +57,7 @@ public class MixinOptionsScreen extends Screen
|
||||
private void lodconfig$init(CallbackInfo ci)
|
||||
{
|
||||
if (Config.Client.optionsButton.get())
|
||||
this. #if PRE_MC_1_17_1 addButton #else addRenderableWidget #endif
|
||||
this. #if MC_VER < MC_1_17_1 addButton #else addRenderableWidget #endif
|
||||
(new TexturedButtonWidget(
|
||||
// Where the button is on the screen
|
||||
this.width / 2 - 180, this.height / 6 - 12,
|
||||
@@ -71,7 +71,7 @@ public class MixinOptionsScreen extends Screen
|
||||
// For now it goes to the client option by default
|
||||
(buttonWidget) -> Objects.requireNonNull(minecraft).setScreen(GetConfigScreen.getScreen(this)),
|
||||
// Add a title to the button
|
||||
#if PRE_MC_1_19_2
|
||||
#if MC_VER < MC_1_19_2
|
||||
new TranslatableComponent(ModInfo.ID + ".title")));
|
||||
#else
|
||||
Component.translatable(ModInfo.ID + ".title")));
|
||||
|
||||
+1
-1
@@ -22,7 +22,7 @@ package com.seibel.distanthorizons.forge.mixins.server;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import net.minecraft.world.level.chunk.ChunkGenerator;
|
||||
|
||||
#if PRE_MC_1_18_2
|
||||
#if MC_VER < MC_1_18_2
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user