Compare commits
383 Commits
2.0.1a
..
java_omega
| Author | SHA1 | Date | |
|---|---|---|---|
| 0c8b3f3cda | |||
| a9a6a19307 | |||
| 208fc69eb7 | |||
| eb1a062934 | |||
| 132251341f | |||
| 2bac5f933a | |||
| 2e565aa83a | |||
| 4e9d0f4861 | |||
| 7216b193e8 | |||
| c33a5bf814 | |||
| 97756a5196 | |||
| 377f7d23e3 | |||
| 7005202384 | |||
| 99e8f57bac | |||
| afddf4168e | |||
| fbffdc0c9f | |||
| e6d3647490 | |||
| 13363ff363 | |||
| 7f98e4b1eb | |||
| 408460b0ae | |||
| b69ef5835d | |||
| 0428fa0912 | |||
| 9f3124fa56 | |||
| fbbdab73c6 | |||
| ee9441c521 | |||
| a9e0fd5d9b | |||
| 98464889ca | |||
| eed5fd60c6 | |||
| ac43cd5496 | |||
| 1f16a7c808 | |||
| 39e4c70754 | |||
| 82eb27af4c | |||
| 07a0779ca4 | |||
| 2adba02a38 | |||
| 9dd76db3fc | |||
| 97dacf2429 | |||
| 1c189e162a | |||
| f7a0fff869 | |||
| 2f985d0926 | |||
| 2a3c544fba | |||
| 09d133b994 | |||
| 26a4223ecf | |||
| e2943fdcaf | |||
| f1053251b4 | |||
| be1dcaf43c | |||
| a899d988fc | |||
| 06b5b2c514 | |||
| 864a19b79f | |||
| 8974323406 | |||
| 46c9e0103a | |||
| 02203466ed | |||
| 87b22ea1cc | |||
| d26327a930 | |||
| 469d2bdcb7 | |||
| 5516603a0c | |||
| b737adc3da | |||
| f3a8afeee3 | |||
| a4501f86e9 | |||
| 095fff96ff | |||
| a23211d061 | |||
| b57ea41686 | |||
| 62fb5ffb73 | |||
| 99c713967b | |||
| 9f3de07bd8 | |||
| cd74117de3 | |||
| e7d7033548 | |||
| 34db7c9dac | |||
| 272841aae9 | |||
| 389b09a5cd | |||
| 84bd876c71 | |||
| 7e45051ffd | |||
| 5570f3a313 | |||
| f4e71f7012 | |||
| 601d4e6e3a | |||
| a12092c1a1 | |||
| 94ad118c5d | |||
| 48e2978438 | |||
| 96b4c1a9e8 | |||
| cc4a69c10c | |||
| 7293677ddb | |||
| 0f2ff20375 | |||
| 7706240acb | |||
| 4cf48fd997 | |||
| 2708c1ee11 | |||
| ebb0f6ebad | |||
| 2c263a2549 | |||
| 955524c632 | |||
| 564e0d3263 | |||
| c533b2e8ea | |||
| 6073d8122a | |||
| 71ca26bba9 | |||
| 75a51be28c | |||
| a66e4ba157 | |||
| 55d5bca76d | |||
| f81026c707 | |||
| e86af817e0 | |||
| e0fd2b2f7a | |||
| f2b9e428d3 | |||
| 5b2497b9d4 | |||
| e78424def4 | |||
| e2c94de6e6 | |||
| daa3caf684 | |||
| 5991aa42d9 | |||
| ff6a5aae69 | |||
| 80d9b4540b | |||
| 4998991ebe | |||
| 14343569fe | |||
| be6cc5ff4e | |||
| 0ad3391bea | |||
| 582d998e2e | |||
| c00ee26075 | |||
| 4c9f70a52f | |||
| 29481bc123 | |||
| e274c9e004 | |||
| 73988f0308 | |||
| c4a9e7a2a7 | |||
| af6dca6e5e | |||
| a49720a221 | |||
| 12a66e70c9 | |||
| 00d8aa356b | |||
| d40d94a565 | |||
| c1f798793e | |||
| 8fe4ad454c | |||
| 17022f2df2 | |||
| 7fa4bc35f6 | |||
| 85df9c5ef4 | |||
| 45d4f390a9 | |||
| e7b60b7562 | |||
| 2615177907 | |||
| a83d7e2a26 | |||
| 8a2182e238 | |||
| d45455092c | |||
| da18469fd4 | |||
| 6b5bae9bee | |||
| e29a7786e4 | |||
| 55a837ca5e | |||
| 94cba6cf67 | |||
| 294685df00 | |||
| 2642b7a9a4 | |||
| 45594e4e47 | |||
| 54cd1a2e48 | |||
| a20fb982ec | |||
| 184d61e637 | |||
| 06ea56767f | |||
| 1f6e137759 | |||
| c7cf7885ae | |||
| 8e98444887 | |||
| 9bfe2e8233 | |||
| 21f4adc769 | |||
| 3b10ca5809 | |||
| 6cc8284747 | |||
| 6254f7156f | |||
| 0fa03701a4 | |||
| 49125cae47 | |||
| 3298857d0c | |||
| d939cbeb96 | |||
| 54d254be73 | |||
| d433fdea62 | |||
| ffa1c54ff3 | |||
| 019ac6dec3 | |||
| 08d3da47f4 | |||
| 348ac2b734 | |||
| fe014b4985 | |||
| b7f6f3b900 | |||
| 3c76ed71d8 | |||
| 5de1998913 | |||
| 05c0f030cb | |||
| bd85329589 | |||
| da0f4ae326 | |||
| b37e568372 | |||
| b1c6a5c1d4 | |||
| 8222126e8f | |||
| b5b888c69f | |||
| 85f6b8320b | |||
| 6c4740e8aa | |||
| ffda83c25d | |||
| 18859d22a8 | |||
| befa3b375e | |||
| a96c08cad4 | |||
| d7f789c402 | |||
| ed28bcd0ba | |||
| 982ae0c0a0 | |||
| d17897f276 | |||
| c0ccef7e82 | |||
| 55e5c64c68 | |||
| da72f783ed | |||
| 8a9bfa3d33 | |||
| 82937d840a | |||
| c1bd358502 | |||
| a8a22fd9fe | |||
| adb70857fe | |||
| a680596b3e | |||
| b2986ec782 | |||
| f40f7afab3 | |||
| 59555d1ca8 | |||
| 6e2eb7d1ac | |||
| 69483067b4 | |||
| c815591565 | |||
| f82b7ec608 | |||
| 23a107682c | |||
| 26da69c875 | |||
| 8f2df2396d | |||
| dbc9cbb418 | |||
| 09c788e495 | |||
| 9af71ac0ea | |||
| 2db20f8f24 | |||
| 2c9827c227 | |||
| 825b1ab4db | |||
| c61faac06c | |||
| 6b442f03c1 | |||
| 10ab638643 | |||
| d349d0c453 | |||
| e5c948ce9c | |||
| c51255f379 | |||
| 5bbeceee56 | |||
| ee78920a88 | |||
| 138972cf18 | |||
| 1bda767cd7 | |||
| cf1402edb9 | |||
| 778144a553 | |||
| fcca51a8d9 | |||
| 3cc663ee95 | |||
| 52f15a86fd | |||
| 734bb4afb8 | |||
| 9cd48fb5d7 | |||
| cd5c3d9f13 | |||
| 73ba1c8b56 | |||
| 8199b4408a | |||
| c00e3d7393 | |||
| 5d60251da0 | |||
| 855d707b3e | |||
| 592a1c3601 | |||
| da280db0f8 | |||
| 0ee6673e68 | |||
| 8bedb3dbaa | |||
| ea0e24b430 | |||
| cd35461df6 | |||
| 40580e81c2 | |||
| 1a279b90be | |||
| e34203fe3d | |||
| 870c0f68d3 | |||
| 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 |
@@ -34,3 +34,9 @@ build.properties
|
|||||||
|
|
||||||
# Sqlite databases
|
# Sqlite databases
|
||||||
*.sqlite
|
*.sqlite
|
||||||
|
*.sqlite-journal
|
||||||
|
*.sqlite-shm
|
||||||
|
*.sqlite-wal
|
||||||
|
|
||||||
|
# Don't add access transformers to git as they're dynamically generated
|
||||||
|
accesstransformer.cfg
|
||||||
|
|||||||
+12
-5
@@ -1,6 +1,6 @@
|
|||||||
# use Eclipse's JDK
|
# use Eclipse's JDK
|
||||||
# The ci should always use a unix(-like) OS to work
|
# The ci should always use a unix(-like) OS to work
|
||||||
image: eclipse-temurin:17
|
image: eclipse-temurin:21
|
||||||
|
|
||||||
# all stages need to be defined here
|
# all stages need to be defined here
|
||||||
# TODO: Make stages depend on what is in versionProperties
|
# TODO: Make stages depend on what is in versionProperties
|
||||||
@@ -30,7 +30,7 @@ build:
|
|||||||
stage: build
|
stage: build
|
||||||
parallel:
|
parallel:
|
||||||
matrix:
|
matrix:
|
||||||
- MC_VER: ["1.16.5", "1.17.1", "1.18.2", "1.19.2", "1.19.4", "1.20.1", "1.20.2"]
|
- MC_VER: ["1.16.5", "1.17.1", "1.18.2", "1.19.2", "1.19.4", "1.20.1", "1.20.2", "1.20.4", "1.20.6", "1.21"]
|
||||||
script:
|
script:
|
||||||
# this both runs the unit tests and assembles the code
|
# this both runs the unit tests and assembles the code
|
||||||
- ./gradlew clean -PmcVer="${MC_VER}" -PinfoGitCommit="${CI_COMMIT_SHA}" -PinfoGitBranch="${CI_COMMIT_BRANCH}" -PinfoBuildSource="GitLab CI (${CI_PIPELINE_ID})" --gradle-user-home cache/;
|
- ./gradlew clean -PmcVer="${MC_VER}" -PinfoGitCommit="${CI_COMMIT_SHA}" -PinfoGitBranch="${CI_COMMIT_BRANCH}" -PinfoBuildSource="GitLab CI (${CI_PIPELINE_ID})" --gradle-user-home cache/;
|
||||||
@@ -40,17 +40,24 @@ build:
|
|||||||
name: "NightlyBuild_${MC_VER}-${CI_COMMIT_SHORT_SHA}-${CI_COMMIT_TIMESTAMP}"
|
name: "NightlyBuild_${MC_VER}-${CI_COMMIT_SHORT_SHA}-${CI_COMMIT_TIMESTAMP}"
|
||||||
paths:
|
paths:
|
||||||
- Merged/*.jar
|
- Merged/*.jar
|
||||||
|
- quilt/build/libs/*.jar
|
||||||
- fabric/build/libs/*.jar
|
- fabric/build/libs/*.jar
|
||||||
- forge/build/libs/*.jar
|
- forge/build/libs/*.jar
|
||||||
- quilt/build/libs/*.jar
|
- neoforge/build/libs/*.jar
|
||||||
exclude:
|
exclude:
|
||||||
# TODO: There is a lot of duplicate stuff here, try to maybe make it smaller
|
# TODO: There is a lot of duplicate stuff here, try to maybe make it smaller
|
||||||
- fabric/build/libs/*-all.jar
|
- fabric/build/libs/*-all.jar
|
||||||
|
- fabric/build/libs/*-dev.jar
|
||||||
- fabric/build/libs/*-sources.jar
|
- fabric/build/libs/*-sources.jar
|
||||||
- forge/build/libs/*-all.jar
|
|
||||||
- forge/build/libs/*-sources.jar
|
|
||||||
- quilt/build/libs/*-all.jar
|
- quilt/build/libs/*-all.jar
|
||||||
|
- quilt/build/libs/*-dev.jar
|
||||||
- quilt/build/libs/*-sources.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
|
expire_in: 14 days
|
||||||
when: always
|
when: always
|
||||||
extends: .build_java
|
extends: .build_java
|
||||||
|
|||||||
@@ -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:
|
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:
|
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:
|
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. \
|
4. [ ] Upload Minecraft's crash report and/or log. \
|
||||||
Minecraft crash reports are located in: `.minecraft/crash-reports` \
|
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. **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**:
|
2. **Describe the improvement**:
|
||||||
|
|||||||
@@ -1,18 +1,16 @@
|
|||||||
# <img src="https://gitlab.com/jeseibel/distant-horizons-core/-/raw/main/_Misc%20Files/logo%20files/LOD%20logo%20flat%20-%20with%20boarder.png" width="32"> Distant Horizons
|
# <img src="https://gitlab.com/jeseibel/distant-horizons-core/-/raw/main/_Misc%20Files/logo%20files/LOD%20logo%20flat%20-%20with%20boarder.png" width="32"> Distant Horizons
|
||||||
|
_See farther without turning your game into a slide show._
|
||||||
|
|
||||||
> A mod that adds a Level of Detail System to Minecraft
|
<br>
|
||||||
|
|
||||||
|
|
||||||
# What is Distant Horizons?
|
# What is Distant Horizons?
|
||||||
|
|
||||||
Distant Horizons is a Minecraft mod that adds a Level Of Detail (LOD) system to\
|
Distant Horizons is a mod which implements a [Level of Detail](https://en.wikipedia.org/wiki/Level_of_detail_(computer_graphics)) system to Minecraft.\
|
||||||
render simplified chunks outside the normal render distance\
|
This allows for far greater render distances without harming performance by gradually lowering the quality of distant terrain.
|
||||||
allowing for an increased view distance without harming performance.
|
|
||||||
|
|
||||||
In other words: this mod lets you see farther without turning your game into a slide show.\
|
Below is a video demonstrating the system:
|
||||||
If you want to see a quick demo, check out a video covering the mod here:
|
|
||||||
|
|
||||||
<a href="https://youtu.be/_04BZ8W2bDM" target="_blank"></a>
|
<a href="https://youtu.be/SxQdbtjGEsc" target="_blank"></a>
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
@@ -20,6 +18,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:
|
### 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
|
#### 1.20.2
|
||||||
Fabric: 0.14.24\
|
Fabric: 0.14.24\
|
||||||
Fabric API: 0.90.4+1.20.2\
|
Fabric API: 0.90.4+1.20.2\
|
||||||
@@ -27,7 +33,7 @@ Forge: 48.0.13\
|
|||||||
Parchment: 1.20.1:2023.09.03\
|
Parchment: 1.20.1:2023.09.03\
|
||||||
Modmenu: 8.0.0
|
Modmenu: 8.0.0
|
||||||
|
|
||||||
#### 1.20.1, 1.20 (Default)
|
#### 1.20.1, 1.20
|
||||||
Fabric: 0.14.24\
|
Fabric: 0.14.24\
|
||||||
Fabric API: 0.90.4+1.20.1\
|
Fabric API: 0.90.4+1.20.1\
|
||||||
Forge: 47.2.1\
|
Forge: 47.2.1\
|
||||||
@@ -73,14 +79,15 @@ Modmenu: 1.16.22
|
|||||||
- 1.18.1, 1.18
|
- 1.18.1, 1.18
|
||||||
- 1.19.1, 1.19
|
- 1.19.1, 1.19
|
||||||
- 1.19.3
|
- 1.19.3
|
||||||
<br><br>
|
|
||||||
|
<br>
|
||||||
|
|
||||||
### Plugin and Library versions
|
### Plugin and Library versions
|
||||||
|
|
||||||
Fabric loom: 1.1.+\
|
Gradle: 8.5\
|
||||||
Forge gradle (Using Architectury): 3.4-SNAPSHOT\
|
Fabric loom: 1.4-SNAPSHOT\
|
||||||
|
Architectury loom (Forge gradle replacement): 1.4-SNAPSHOT\
|
||||||
Sponge vanilla gradle: 0.2.1-SNAPSHOT\
|
Sponge vanilla gradle: 0.2.1-SNAPSHOT\
|
||||||
Sponge mixin: 0.8.5\
|
|
||||||
Java Preprocessor plugin: Manifold Preprocessor
|
Java Preprocessor plugin: Manifold Preprocessor
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
@@ -93,7 +100,7 @@ Java Preprocessor plugin: Manifold Preprocessor
|
|||||||
Visit https://www.oracle.com/java/technologies/downloads/ for installers.
|
Visit https://www.oracle.com/java/technologies/downloads/ for installers.
|
||||||
* Git or someway to clone git projects. <br>
|
* Git or someway to clone git projects. <br>
|
||||||
Visit https://git-scm.com/ for installers.
|
Visit https://git-scm.com/ for installers.
|
||||||
* (Not required) Any Java IDE with plugins that support Manifold, for example Intellij IDEA.
|
* (Not required) Any Java IDE with plugins that support Manifold, for example IntelliJ IDEA.
|
||||||
|
|
||||||
**If using IntelliJ:**
|
**If using IntelliJ:**
|
||||||
1. Install the Manifold plugin
|
1. Install the Manifold plugin
|
||||||
@@ -106,17 +113,14 @@ Java Preprocessor plugin: Manifold Preprocessor
|
|||||||
3. Make sure eclipse has the JDK 17 installed. (This is needed so that eclipse can run minecraft)
|
3. Make sure eclipse has the JDK 17 installed. (This is needed so that eclipse can run minecraft)
|
||||||
4. Import the project into eclipse
|
4. Import the project into eclipse
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
## Switching Versions
|
## Switching Versions
|
||||||
|
|
||||||
To switch between different Minecraft versions, change `mcVer=1.?` in the `gradle.properties` file.
|
To switch between different Minecraft versions, change `mcVer=1.?` in the `gradle.properties` file.
|
||||||
|
|
||||||
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.)
|
If running in an IDE, to ensure the IDE noticed the version change, run any gradle command to refresh gradle.\
|
||||||
>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`). \
|
In IntelliJ, you will also need to do a gradle sync if it didn't happen automatically.
|
||||||
> If anyone knows how to solve this issue please let us know here: \
|
|
||||||
> https://gitlab.com/jeseibel/minecraft-lod-mod/-/issues/233
|
|
||||||
|
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
@@ -130,21 +134,20 @@ From the File Explorer:
|
|||||||
2. Download the core from https://gitlab.com/jeseibel/distant-horizons-core and extract into a folder called `coreSubProjects`
|
2. Download the core from https://gitlab.com/jeseibel/distant-horizons-core and extract into a folder called `coreSubProjects`
|
||||||
3. Open a terminal emulator in the project folder (On Windows you can type `cmd` in the title bar)
|
3. Open a terminal emulator in the project folder (On Windows you can type `cmd` in the title bar)
|
||||||
4. Run the commands: `./gradlew assemble` (You may need to use a `.\` on Windows)
|
4. Run the commands: `./gradlew assemble` (You may need to use a `.\` on Windows)
|
||||||
5. Merge the jars wih `./gradlew mergeJars`
|
5. Merge the jars with `./gradlew mergeJars`
|
||||||
6. The compiled jar file will be in the folder `Merged`
|
6. The compiled jar file will be in the folder `Merged`
|
||||||
|
|
||||||
From the command line:
|
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`
|
2. `cd distant-horizons`
|
||||||
3. `./gradlew assemble`
|
3. `./gradlew assemble`
|
||||||
4. `./gradlew mergeJars`
|
4. `./gradlew mergeJars`
|
||||||
5. The compiled jar file will be in the folder `Merged`
|
5. The compiled jar file will be in the folder `Merged`
|
||||||
|
|
||||||
Run tests with: `./gradlew test`
|
Run tests with: `./gradlew test`
|
||||||
|
|
||||||
>Note: You can add the arg: `-PmcVer=?` to tell gradle to build a selected MC version instead of having to modify the `gradle.properties` file. \
|
>Note: You can add the argument `-PmcVer=?` to tell gradle to build a selected MC version instead of having to modify the `gradle.properties` file.\
|
||||||
> Example: `./gradlew assemble -PmcVer=1.18.2`
|
> For example: `./gradlew assemble -PmcVer=1.18.2`
|
||||||
|
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
@@ -154,7 +157,6 @@ Run tests with: `./gradlew test`
|
|||||||
|
|
||||||
You can also locally compile the DH jars without a Java environment by using Docker. Where `<version>` is the version of Minecraft to compile for (ie `1.20.1`), or the keyword `all`. See [Versions](#minecraft-and-library-versions) for a list of all supported values.
|
You can also locally compile the DH jars without a Java environment by using Docker. Where `<version>` is the version of Minecraft to compile for (ie `1.20.1`), or the keyword `all`. See [Versions](#minecraft-and-library-versions) for a list of all supported values.
|
||||||
|
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
## Other commands
|
## Other commands
|
||||||
@@ -163,6 +165,7 @@ You can also locally compile the DH jars without a Java environment by using Doc
|
|||||||
|
|
||||||
`./gradlew clean` to delete any compiled code.
|
`./gradlew clean` to delete any compiled code.
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
## Note to self
|
## Note to self
|
||||||
|
|
||||||
@@ -170,7 +173,7 @@ The Minecraft source code is NOT added to your workspace in an editable way. Min
|
|||||||
|
|
||||||
Source code uses Mojang mappings & [Parchment](https://parchmentmc.org/) mappings.
|
Source code uses Mojang mappings & [Parchment](https://parchmentmc.org/) mappings.
|
||||||
|
|
||||||
To generate the source code run `./gradlew genSources`\
|
To generate the source code run `./gradlew genSources` <br>
|
||||||
If your IDE fails to auto-detect the source jars when browsing Minecraft classes; manually select the JAR file ending with -sources.jar when prompted by your IDE. <br>
|
If your IDE fails to auto-detect the source jars when browsing Minecraft classes; manually select the JAR file ending with -sources.jar when prompted by your IDE. <br>
|
||||||
(In IntelliJ it's at the top where it says "choose sources" when browsing a Minecraft class)
|
(In IntelliJ it's at the top where it says "choose sources" when browsing a Minecraft class)
|
||||||
|
|
||||||
@@ -178,12 +181,12 @@ If your IDE fails to auto-detect the source jars when browsing Minecraft classes
|
|||||||
|
|
||||||
## Other Useful commands
|
## Other Useful commands
|
||||||
|
|
||||||
Run the standalone jar: `./gradlew run`\
|
Run the standalone jar: `./gradlew run` <br>
|
||||||
Build the standalone jar: `./gradlew core:build`\
|
Build the standalone jar: `./gradlew core:build` <br>
|
||||||
Only build Fabric: `./gradlew fabric:assemble` or `./gradlew fabric:build`\
|
Only build Fabric: `./gradlew fabric:assemble` or `./gradlew fabric:build` <br>
|
||||||
Only build Forge: `./gradlew fabric:assemble` or `./gradlew forge:build`\
|
Only build Forge: `./gradlew forge:assemble` or `./gradlew forge:build` <br>
|
||||||
Run the Fabric client (for debugging): `./gradlew fabric:runClient`\
|
Run the Fabric client (for debugging): `./gradlew fabric:runClient` <br>
|
||||||
Run the Forge client (for debugging): `./gradlew forge:runClient`
|
Run the Forge client (for debugging): `./gradlew forge:runClient` <br>
|
||||||
|
|
||||||
To build all versions: `./buildAll` (all builds will end up in the `Merged` folder)
|
To build all versions: `./buildAll` (all builds will end up in the `Merged` folder)
|
||||||
|
|
||||||
@@ -197,7 +200,7 @@ https://github.com/PacifistMC/Forgix
|
|||||||
LZ4 for Java (data compression)\
|
LZ4 for Java (data compression)\
|
||||||
https://github.com/lz4/lz4-java
|
https://github.com/lz4/lz4-java
|
||||||
|
|
||||||
NightConfig for Json & Toml (config handling)\
|
NightConfig for JSON & TOML (config handling)\
|
||||||
https://github.com/TheElectronWill/night-config
|
https://github.com/TheElectronWill/night-config
|
||||||
|
|
||||||
SVG Salamander for SVG support (not being used atm)\
|
SVG Salamander for SVG support (not being used atm)\
|
||||||
|
|||||||
+105
-128
@@ -1,77 +1,54 @@
|
|||||||
plugins {
|
plugins {
|
||||||
id "java"
|
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
|
id "com.github.johnrengelman.shadow" version '8.1.1' apply false
|
||||||
|
|
||||||
// Plugin to create merged jars
|
// Plugin to create merged jars
|
||||||
id "io.github.pacifistmc.forgix" version "1.2.6"
|
id "io.github.pacifistmc.forgix" version "1.2.9"
|
||||||
|
|
||||||
// Manifold preprocessor
|
// Manifold preprocessor
|
||||||
id "systems.manifold.manifold-gradle-plugin" version "0.0.2-alpha"
|
id "systems.manifold.manifold-gradle-plugin" version "0.0.2-alpha"
|
||||||
|
|
||||||
// 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
|
// Architectury is used here only as a replacement for forge's own loom
|
||||||
id "dev.architectury.loom" version "1.1.+" apply false
|
id "dev.architectury.loom" version "1.6-SNAPSHOT" apply false
|
||||||
|
|
||||||
|
id 'xyz.wagyourtail.jvmdowngrader' version '0.9.1' apply true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates the list of preprocessors to use.
|
* Creates the list of preprocessors to use.
|
||||||
*
|
*
|
||||||
* @param mcVers array of all MC versions
|
* @param mcVers array of all MC versions
|
||||||
* @param mcIndex array index of the currently active MC version
|
* @param mcIndex array index of the currently active MC version
|
||||||
*/
|
*/
|
||||||
def writeBuildGradlePredefine(List<String> mcVers, int mcIndex) {
|
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
|
// Build the list of preprocessors to use
|
||||||
StringBuilder sb = new StringBuilder()
|
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");
|
||||||
|
}
|
||||||
|
|
||||||
sb.append("# DON'T TOUCH THIS FILE, This is handled by the build script\n")
|
|
||||||
|
|
||||||
// Check if this is a development build
|
// Check if this is a development build
|
||||||
if (mod_version.toLowerCase().contains("dev")) {
|
if (mod_version.toLowerCase().contains("dev"))
|
||||||
|
{
|
||||||
// WARNING: only use this for logging, we don't want to have confusion
|
// WARNING: only use this for logging, we don't want to have confusion
|
||||||
// when a method doesn't work correctly in the release build.
|
// when a method doesn't work correctly in the release build.
|
||||||
sb.append("DEV_BUILD")
|
sb.append("DEV_BUILD=\n");
|
||||||
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()
|
new File(projectDir, "build.properties").text = sb.toString()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -79,7 +56,7 @@ def writeBuildGradlePredefine(List<String> mcVers, int mcIndex) {
|
|||||||
// Transfers the values set in settings.gradle to the rest of the project
|
// Transfers the values set in settings.gradle to the rest of the project
|
||||||
project.gradle.ext.getProperties().each { prop ->
|
project.gradle.ext.getProperties().each { prop ->
|
||||||
rootProject.ext.set(prop.key, prop.value)
|
rootProject.ext.set(prop.key, prop.value)
|
||||||
// println "Added prop [key:" + prop.key + ", value:" + prop.value + "]"
|
//println "Added prop [key:" + prop.key + ", value:" + prop.value + "]"
|
||||||
}
|
}
|
||||||
// Sets up manifold stuff
|
// Sets up manifold stuff
|
||||||
writeBuildGradlePredefine(rootProject.mcVers, rootProject.mcIndex)
|
writeBuildGradlePredefine(rootProject.mcVers, rootProject.mcIndex)
|
||||||
@@ -99,6 +76,12 @@ forgix {
|
|||||||
jarLocation = "build/libs/DistantHorizons-forge-${rootProject.versionStr}.jar"
|
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"))
|
if (findProject(":fabric"))
|
||||||
fabric {
|
fabric {
|
||||||
jarLocation = "build/libs/DistantHorizons-fabric-${rootProject.versionStr}.jar"
|
jarLocation = "build/libs/DistantHorizons-fabric-${rootProject.versionStr}.jar"
|
||||||
@@ -121,14 +104,12 @@ subprojects { p ->
|
|||||||
// Apply plugins
|
// Apply plugins
|
||||||
apply plugin: "java"
|
apply plugin: "java"
|
||||||
apply plugin: "com.github.johnrengelman.shadow"
|
apply plugin: "com.github.johnrengelman.shadow"
|
||||||
|
apply plugin: "xyz.wagyourtail.jvmdowngrader"
|
||||||
if (isMinecraftSubProject)
|
if (isMinecraftSubProject)
|
||||||
apply plugin: "systems.manifold.manifold-gradle-plugin"
|
apply plugin: "systems.manifold.manifold-gradle-plugin"
|
||||||
if (p == project(":core"))
|
|
||||||
apply plugin: "application"
|
|
||||||
// apply plugin: "org.spongepowered.gradle.vanilla" // Provides minecraft libraries
|
|
||||||
|
|
||||||
// Apply forge's loom
|
// Apply forge's loom
|
||||||
if (findProject(":forge") && p == project(":forge"))
|
if ( (findProject(":forge") && p == project(":forge")) || (findProject(":neoforge") && p == project(":neoforge")) )
|
||||||
apply plugin: "dev.architectury.loom"
|
apply plugin: "dev.architectury.loom"
|
||||||
|
|
||||||
|
|
||||||
@@ -166,10 +147,16 @@ subprojects { p ->
|
|||||||
shadowCommon // Don't use shadow from the shadow plugin because we don't want IDEA to index this.
|
shadowCommon // Don't use shadow from the shadow plugin because we don't want IDEA to index this.
|
||||||
compileClasspath.extendsFrom common
|
compileClasspath.extendsFrom common
|
||||||
runtimeClasspath.extendsFrom common
|
runtimeClasspath.extendsFrom common
|
||||||
|
if (findProject(":forge"))
|
||||||
developmentForge.extendsFrom common
|
developmentForge.extendsFrom common
|
||||||
|
if (findProject(":neoforge"))
|
||||||
|
developmentNeoForge.extendsFrom common
|
||||||
compileClasspath.extendsFrom coreProjects
|
compileClasspath.extendsFrom coreProjects
|
||||||
runtimeClasspath.extendsFrom coreProjects
|
runtimeClasspath.extendsFrom coreProjects
|
||||||
|
if (findProject(":forge"))
|
||||||
developmentForge.extendsFrom coreProjects
|
developmentForge.extendsFrom coreProjects
|
||||||
|
if (findProject(":neoforge"))
|
||||||
|
developmentNeoForge.extendsFrom coreProjects
|
||||||
|
|
||||||
if (findProject(":fabricLike") && p != project(":fabricLike")) {
|
if (findProject(":fabricLike") && p != project(":fabricLike")) {
|
||||||
// Shadow fabricLike
|
// Shadow fabricLike
|
||||||
@@ -177,26 +164,16 @@ subprojects { p ->
|
|||||||
shadowFabricLike
|
shadowFabricLike
|
||||||
compileClasspath.extendsFrom fabricLike
|
compileClasspath.extendsFrom fabricLike
|
||||||
runtimeClasspath.extendsFrom fabricLike
|
runtimeClasspath.extendsFrom fabricLike
|
||||||
developmentForge.extendsFrom fabricLike
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Let the application plugin know where the main class is
|
|
||||||
// (This will point to a non-existent class in all sub-projects except "Core")
|
|
||||||
if (p == project(":core")) {
|
|
||||||
application {
|
|
||||||
mainClass.set("com.seibel.distanthorizons.core.jar.JarMain")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
//=====================//
|
//=====================//
|
||||||
// shared dependencies //
|
// shared dependencies //
|
||||||
//=====================//
|
//=====================//
|
||||||
|
|
||||||
|
|
||||||
// Manifold
|
// Manifold
|
||||||
if (isMinecraftSubProject) {
|
if (isMinecraftSubProject) {
|
||||||
annotationProcessor("systems.manifold:manifold-preprocessor:${rootProject.manifold_version}")
|
annotationProcessor("systems.manifold:manifold-preprocessor:${rootProject.manifold_version}")
|
||||||
@@ -209,6 +186,9 @@ subprojects { p ->
|
|||||||
implementation("org.apache.logging.log4j:log4j-core:${rootProject.log4j_version}")
|
implementation("org.apache.logging.log4j:log4j-core:${rootProject.log4j_version}")
|
||||||
|
|
||||||
// JOML
|
// JOML
|
||||||
|
if (project.hasProperty("embed_joml") && embed_joml == "true")
|
||||||
|
forgeShadowMe("org.joml:joml:${rootProject.joml_version}")
|
||||||
|
else
|
||||||
implementation("org.joml:joml:${rootProject.joml_version}")
|
implementation("org.joml:joml:${rootProject.joml_version}")
|
||||||
|
|
||||||
// JUnit tests
|
// JUnit tests
|
||||||
@@ -216,8 +196,15 @@ subprojects { p ->
|
|||||||
implementation("org.junit.jupiter:junit-jupiter-engine:5.8.2")
|
implementation("org.junit.jupiter:junit-jupiter-engine:5.8.2")
|
||||||
implementation("junit:junit:4.13")
|
implementation("junit:junit:4.13")
|
||||||
|
|
||||||
|
// FastUtil
|
||||||
|
// Note: MC 1.16 uses 8.2.1, and versions after use 8.5.12
|
||||||
|
// We cannot relocate this library since we call some MC classes that reference it
|
||||||
|
implementation("it.unimi.dsi:fastutil:${rootProject.fastutil_version}")
|
||||||
|
|
||||||
|
|
||||||
// Compression
|
// Compression
|
||||||
forgeShadowMe("org.lz4:lz4-java:${rootProject.lz4_version}")
|
forgeShadowMe("org.lz4:lz4-java:${rootProject.lz4_version}") // LZ4
|
||||||
|
forgeShadowMe("org.tukaani:xz:${rootProject.xz_version}") // LZMA
|
||||||
|
|
||||||
// Sqlite Database
|
// Sqlite Database
|
||||||
forgeShadowMe("org.xerial:sqlite-jdbc:${rootProject.sqlite_jdbc_version}")
|
forgeShadowMe("org.xerial:sqlite-jdbc:${rootProject.sqlite_jdbc_version}")
|
||||||
@@ -295,7 +282,7 @@ subprojects { p ->
|
|||||||
relocate "com.seibel.distanthorizons.fabriclike", "loaderCommon.${p.name}.com.seibel.distanthorizons.fabriclike" // Move the loader files to a different location
|
relocate "com.seibel.distanthorizons.fabriclike", "loaderCommon.${p.name}.com.seibel.distanthorizons.fabriclike" // Move the loader files to a different location
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
def librariesLocation = "distanthorizons.libraries"
|
def librariesLocation = "DistantHorizons.libraries"
|
||||||
|
|
||||||
// LWJGL
|
// LWJGL
|
||||||
// Only ever shadow the dependencies we use otherwise some stuff would break when running on an external client
|
// Only ever shadow the dependencies we use otherwise some stuff would break when running on an external client
|
||||||
@@ -308,6 +295,10 @@ subprojects { p ->
|
|||||||
//At the moment, there is a bug in this library which doesnt allow it to be relocated
|
//At the moment, there is a bug in this library which doesnt allow it to be relocated
|
||||||
// relocate "org.sqlite", "${librariesLocation}.sqlite"
|
// relocate "org.sqlite", "${librariesLocation}.sqlite"
|
||||||
|
|
||||||
|
// JOML
|
||||||
|
if (project.hasProperty("embed_joml") && embed_joml == "true")
|
||||||
|
relocate "org.joml", "${librariesLocation}.joml"
|
||||||
|
|
||||||
// NightConfig (includes Toml & Json)
|
// NightConfig (includes Toml & Json)
|
||||||
relocate "com.electronwill.nightconfig", "${librariesLocation}.electronwill.nightconfig"
|
relocate "com.electronwill.nightconfig", "${librariesLocation}.electronwill.nightconfig"
|
||||||
|
|
||||||
@@ -319,8 +310,21 @@ subprojects { p ->
|
|||||||
|
|
||||||
mergeServiceFiles()
|
mergeServiceFiles()
|
||||||
}
|
}
|
||||||
// Using jar.finalizedBy(shadowJar) causes issues so we do this scuffed bypass
|
|
||||||
jar.dependsOn(shadowJar)
|
// For downgrading the Java version of our project to match the minimum Java version required by the selected Minecraft version.
|
||||||
|
task jarDowngrade(type: xyz.wagyourtail.jvmdg.gradle.task.DowngradeJar) {
|
||||||
|
inputFile = tasks.shadowJar.archiveFile
|
||||||
|
downgradeTo = JavaVersion.toVersion(rootProject.java_version as Integer)
|
||||||
|
archiveClassifier = "downgraded-${rootProject.java_version}"
|
||||||
|
}
|
||||||
|
task apiDowngrade(type: xyz.wagyourtail.jvmdg.gradle.task.ShadeJar) {
|
||||||
|
inputFile = jarDowngrade.archiveFile
|
||||||
|
downgradeTo = JavaVersion.toVersion(rootProject.java_version as Integer)
|
||||||
|
archiveClassifier = "downgraded-${rootProject.java_version}-shaded-java-api"
|
||||||
|
}
|
||||||
|
// We're using a custom downgrade task so we disable the original downgrade tasks
|
||||||
|
downgradeJar.enabled = false
|
||||||
|
shadeDowngradedApi.enabled = false
|
||||||
|
|
||||||
|
|
||||||
// Put stuff from gradle.properties into the mod info
|
// Put stuff from gradle.properties into the mod info
|
||||||
@@ -334,6 +338,7 @@ subprojects { p ->
|
|||||||
"fabric.mod.json",
|
"fabric.mod.json",
|
||||||
"quilt.mod.json",
|
"quilt.mod.json",
|
||||||
"META-INF/mods.toml",
|
"META-INF/mods.toml",
|
||||||
|
"META-INF/neoforge.mods.toml",
|
||||||
|
|
||||||
// The mixins for each of the loaders
|
// The mixins for each of the loaders
|
||||||
"DistantHorizons."+ p.name +".fabricLike.mixins.json"
|
"DistantHorizons."+ p.name +".fabricLike.mixins.json"
|
||||||
@@ -341,7 +346,7 @@ subprojects { p ->
|
|||||||
def intoTargets = ["$buildDir/resources/main/"] // Location of the built resources folder
|
def intoTargets = ["$buildDir/resources/main/"] // Location of the built resources folder
|
||||||
|
|
||||||
// Fix forge version numbering system as it is weird
|
// 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("]", ",)")
|
def compatible_forgemc_versions = "${compatible_minecraft_versions}".replaceAll("\"", "").replaceAll("]", ",)")
|
||||||
// println compatible_forgemc_versions
|
// println compatible_forgemc_versions
|
||||||
|
|
||||||
@@ -354,9 +359,9 @@ subprojects { p ->
|
|||||||
quilt_contributors.push("\"${dev.strip()}\": \"Developer\"")
|
quilt_contributors.push("\"${dev.strip()}\": \"Developer\"")
|
||||||
}
|
}
|
||||||
quilt_contributors.reverse()
|
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')
|
// println p.tasks.findByName('shadowJar')
|
||||||
|
|
||||||
|
|
||||||
@@ -371,6 +376,7 @@ subprojects { p ->
|
|||||||
println "Git or Git project not found"
|
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 = [
|
def replaceProperties = [
|
||||||
version : mod_version,
|
version : mod_version,
|
||||||
mod_name : mod_readable_name,
|
mod_name : mod_readable_name,
|
||||||
@@ -394,8 +400,8 @@ subprojects { p ->
|
|||||||
fabric_incompatibility_list : fabric_incompatibility_list,
|
fabric_incompatibility_list : fabric_incompatibility_list,
|
||||||
fabric_recommend_list : fabric_recommend_list,
|
fabric_recommend_list : fabric_recommend_list,
|
||||||
]
|
]
|
||||||
// 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
|
inputs.properties replaceProperties
|
||||||
replaceProperties.put "project", project
|
replaceProperties.put "project", project
|
||||||
filesMatching(resourceTargets) {
|
filesMatching(resourceTargets) {
|
||||||
@@ -423,7 +429,7 @@ subprojects { p ->
|
|||||||
//// include "${accessWidenerVersion}.distanthorizons.accesswidener"
|
//// include "${accessWidenerVersion}.distanthorizons.accesswidener"
|
||||||
|
|
||||||
// Jank solution to remove all unused accesswideners
|
// 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 ->
|
exclude { file ->
|
||||||
if (file.name.contains(".distanthorizons.accesswidener") && file.name != "${accessWidenerVersion}.distanthorizons.accesswidener") {
|
if (file.name.contains(".distanthorizons.accesswidener") && file.name != "${accessWidenerVersion}.distanthorizons.accesswidener") {
|
||||||
return true
|
return true
|
||||||
@@ -459,17 +465,10 @@ subprojects { p ->
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Run mergeJars when running build
|
|
||||||
// TODO: Fix later
|
|
||||||
// if (isMinecraftSubProject) {
|
|
||||||
// build.finalizedBy(mergeJars)
|
|
||||||
// assemble.finalizedBy(mergeJars)
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
allprojects { p ->
|
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
|
// Useful later on so we dont have duplicated code
|
||||||
def isMinecraftSubProject = p != project(":core") && p != project(":api")
|
def isMinecraftSubProject = p != project(":core") && p != project(":api")
|
||||||
|
|
||||||
@@ -485,6 +484,19 @@ allprojects { p ->
|
|||||||
// and is used when bookmarking a page
|
// and is used when bookmarking a page
|
||||||
javadoc.title = rootProject.mod_name + "-" + project.name
|
javadoc.title = rootProject.mod_name + "-" + project.name
|
||||||
|
|
||||||
|
// 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 {
|
repositories {
|
||||||
// The central repo
|
// The central repo
|
||||||
@@ -522,14 +534,16 @@ allprojects { p ->
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Required for ModMenu
|
// VanillaGradle and Mixins in common
|
||||||
maven { url "https://maven.terraformersmc.com/" }
|
|
||||||
|
|
||||||
// Required for Mixins & VanillaGradle
|
|
||||||
maven { url "https://repo.spongepowered.org/maven/" }
|
maven { url "https://repo.spongepowered.org/maven/" }
|
||||||
|
|
||||||
// Required for Canvas (mod)
|
// Canvas mod
|
||||||
maven { url "https://maven.vram.io/" }
|
maven { url "https://maven.vram.io/" }
|
||||||
|
// ModMenu mod
|
||||||
|
maven { url "https://maven.terraformersmc.com/" }
|
||||||
|
|
||||||
|
// neoforge
|
||||||
|
maven { url "https://maven.neoforged.net/releases/" }
|
||||||
|
|
||||||
// These 3 are for importing mods that arnt on CursedForge, Modrinth, GitHub, GitLab or anywhere opensource
|
// These 3 are for importing mods that arnt on CursedForge, Modrinth, GitHub, GitLab or anywhere opensource
|
||||||
flatDir {
|
flatDir {
|
||||||
@@ -550,47 +564,9 @@ allprojects { p ->
|
|||||||
includeGroup "forge-mod"
|
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
|
|
||||||
if (p == project(":core")) {
|
|
||||||
OperatingSystem os = org.gradle.nativeplatform.platform.internal.DefaultNativePlatform.currentOperatingSystem;
|
|
||||||
|
|
||||||
// Set the OS lwjgl is using to the current os
|
|
||||||
project.ext.lwjglNatives = "natives-" + os.toFamilyName()
|
|
||||||
|
|
||||||
dependencies { // All of these dependencies are in Vanilla Minecraft, but we need to depend on it as we arent importing Minecraft in the core
|
|
||||||
// Imports most of lwjgl's libraries (well, only the ones that we need)
|
|
||||||
implementation platform("org.lwjgl:lwjgl-bom:${rootProject.lwjgl_version}") // TODO: Use Minecraft's version for lwjgl_version (which changes in nearly every version) instead of a hard defined version for all versions
|
|
||||||
|
|
||||||
// REMEMBER: Dont shadow stuff here, these are just the libs that are included in Minecraft so that the core can use
|
|
||||||
implementation "org.lwjgl:lwjgl"
|
|
||||||
implementation "org.lwjgl:lwjgl-assimp"
|
|
||||||
implementation "org.lwjgl:lwjgl-glfw"
|
|
||||||
implementation "org.lwjgl:lwjgl-openal"
|
|
||||||
implementation "org.lwjgl:lwjgl-opengl"
|
|
||||||
implementation "org.lwjgl:lwjgl-stb"
|
|
||||||
implementation "org.lwjgl:lwjgl-tinyfd"
|
|
||||||
runtimeOnly "org.lwjgl:lwjgl::$lwjglNatives"
|
|
||||||
runtimeOnly "org.lwjgl:lwjgl-assimp::$lwjglNatives"
|
|
||||||
runtimeOnly "org.lwjgl:lwjgl-glfw::$lwjglNatives"
|
|
||||||
runtimeOnly "org.lwjgl:lwjgl-openal::$lwjglNatives"
|
|
||||||
runtimeOnly "org.lwjgl:lwjgl-opengl::$lwjglNatives"
|
|
||||||
runtimeOnly "org.lwjgl:lwjgl-stb::$lwjglNatives"
|
|
||||||
runtimeOnly "org.lwjgl:lwjgl-tinyfd::$lwjglNatives"
|
|
||||||
implementation "org.joml:joml:${rootProject.joml_version}"
|
|
||||||
|
|
||||||
|
|
||||||
// Some other dependencies
|
|
||||||
implementation("org.jetbrains:annotations:16.0.2")
|
|
||||||
implementation("com.google.code.findbugs:jsr305:3.0.2")
|
|
||||||
implementation("com.google.common:google-collect:0.5")
|
|
||||||
implementation("com.google.guava:guava:31.1-jre")
|
|
||||||
implementation("it.unimi.dsi:fastutil:8.5.11")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
task copyCommonLoaderResources(type: Copy) {
|
task copyCommonLoaderResources(type: Copy) {
|
||||||
from project(":common").file("src/main/resources/${accessWidenerVersion}.distanthorizons.accesswidener")
|
from project(":common").file("src/main/resources/${accessWidenerVersion}.distanthorizons.accesswidener")
|
||||||
into(file(p.file("build/resources/main")))
|
into(file(p.file("build/resources/main")))
|
||||||
@@ -612,16 +588,17 @@ allprojects { p ->
|
|||||||
|
|
||||||
tasks.withType(JavaCompile) {
|
tasks.withType(JavaCompile) {
|
||||||
if (isMinecraftSubProject) {
|
if (isMinecraftSubProject) {
|
||||||
options.release = rootProject.java_version as Integer
|
options.release = rootProject.java_version as Integer // Neoforge complains without this
|
||||||
options.compilerArgs += ["-Xplugin:Manifold"]
|
options.compilerArgs += ["-Xplugin:Manifold"]
|
||||||
} else {
|
|
||||||
options.release = 8; // Core & Api should use Java 8 no matter what
|
|
||||||
//options.release = rootProject.java_version as Integer // But if you want to test some stuff, then this can be enabled
|
|
||||||
}
|
}
|
||||||
options.encoding = "UTF-8"
|
options.encoding = "UTF-8"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Sets the project's actual Java version (it's recommended to use this over the `options.release` method above)
|
||||||
java {
|
java {
|
||||||
|
sourceCompatibility = rootProject.java_version
|
||||||
|
targetCompatibility = rootProject.java_version
|
||||||
|
|
||||||
withSourcesJar()
|
withSourcesJar()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+11
-4
@@ -1,3 +1,13 @@
|
|||||||
|
|
||||||
|
// temporary fix for broken spongepowered version
|
||||||
|
buildscript {
|
||||||
|
configurations.configureEach {
|
||||||
|
resolutionStrategy {
|
||||||
|
force 'org.spongepowered:vanillagradle:0.2.1-20240507.024226-82'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
id "org.spongepowered.gradle.vanilla" version "0.2.1-SNAPSHOT"
|
id "org.spongepowered.gradle.vanilla" version "0.2.1-SNAPSHOT"
|
||||||
}
|
}
|
||||||
@@ -8,10 +18,6 @@ minecraft {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
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
|
// So mixins can be written in common
|
||||||
compileOnly group:'org.spongepowered', name:'mixin', version:'0.8.5'
|
compileOnly group:'org.spongepowered', name:'mixin', version:'0.8.5'
|
||||||
}
|
}
|
||||||
@@ -30,3 +36,4 @@ publishing {
|
|||||||
// Add repositories to publish to here.
|
// Add repositories to publish to here.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,182 @@
|
|||||||
|
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() { /* currently unimplemented */ }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//================//
|
||||||
|
// 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, 2);
|
|
||||||
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);
|
|
||||||
|
|
||||||
}
|
|
||||||
-96
@@ -1,96 +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.rendering;
|
|
||||||
|
|
||||||
#if PRE_MC_1_19_4
|
|
||||||
|
|
||||||
import com.mojang.math.Matrix4f;
|
|
||||||
#else
|
|
||||||
|
|
||||||
import org.joml.Matrix4f;
|
|
||||||
#endif
|
|
||||||
import com.seibel.distanthorizons.core.config.Config;
|
|
||||||
import com.seibel.distanthorizons.core.util.RenderUtil;
|
|
||||||
import com.seibel.distanthorizons.coreapi.util.math.Mat4f;
|
|
||||||
import org.lwjgl.opengl.GL15;
|
|
||||||
|
|
||||||
import java.nio.FloatBuffer;
|
|
||||||
|
|
||||||
public class SeamlessOverdraw
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Proof-of-concept experimental option, not intended for normal use. <br>
|
|
||||||
* (Poorly) replaces Minecraft's far clip plane so it lines up with DH's near clip plane.
|
|
||||||
*/
|
|
||||||
public static float[] overwriteMinecraftNearFarClipPlanes(Matrix4f minecraftProjectionMatrix, float previousPartialTicks)
|
|
||||||
{
|
|
||||||
float[] matrixFloatArray;
|
|
||||||
|
|
||||||
#if PRE_MC_1_19_4
|
|
||||||
FloatBuffer matrixFloatBuffer = FloatBuffer.allocate(16);
|
|
||||||
minecraftProjectionMatrix.store(matrixFloatBuffer);
|
|
||||||
matrixFloatArray = matrixFloatBuffer.array();
|
|
||||||
#else
|
|
||||||
// Passing float buffers in caused native code crashes, so we are passing in a float array instead
|
|
||||||
matrixFloatArray = new float[16];
|
|
||||||
minecraftProjectionMatrix.get(matrixFloatArray);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return overwriteMinecraftNearFarClipPlanes(matrixFloatArray, previousPartialTicks);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static float[] overwriteMinecraftNearFarClipPlanes(Mat4f minecraftProjectionMatrix, float previousPartialTicks)
|
|
||||||
{
|
|
||||||
return overwriteMinecraftNearFarClipPlanes(minecraftProjectionMatrix.getValuesAsArray(), previousPartialTicks);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static float[] overwriteMinecraftNearFarClipPlanes(float[] projectionMatrixFloatArray, float previousPartialTicks)
|
|
||||||
{
|
|
||||||
float dhFarClipPlane = RenderUtil.getNearClipPlaneDistanceInBlocks(previousPartialTicks);
|
|
||||||
|
|
||||||
// works for fabric, bad not for forge for some reason :/
|
|
||||||
float farClip = dhFarClipPlane * 5.1f; // magic number found via trial and error, James has no idea what it represents, except that it makes the seam between DH and vanilla rendering pretty close
|
|
||||||
float nearClip = 0.5f; // this causes issues with some vanilla rendering, specifically the wireframe around selected blocks is slightly off. Unfortunately the ratio between the near and far clip plane can't be easily modified without completely screwing up the rendering.
|
|
||||||
|
|
||||||
// these may be the wrong index locations in any version of MC other than 1.18.2
|
|
||||||
projectionMatrixFloatArray[10] = -((farClip + nearClip) / (farClip - nearClip)); // near clip plane
|
|
||||||
projectionMatrixFloatArray[11] = -((2 * farClip * nearClip) / (farClip - nearClip)); // far clip plane
|
|
||||||
|
|
||||||
|
|
||||||
return projectionMatrixFloatArray;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//================//
|
|
||||||
// helper methods //
|
|
||||||
//================//
|
|
||||||
|
|
||||||
public static void applyLegacyProjectionMatrix(float[] projectionMatrixFloatArray)
|
|
||||||
{
|
|
||||||
int glMatrixMode = GL15.glGetInteger(GL15.GL_MATRIX_MODE);
|
|
||||||
GL15.glMatrixMode(GL15.GL_PROJECTION);
|
|
||||||
|
|
||||||
GL15.glLoadMatrixf(projectionMatrixFloatArray);
|
|
||||||
|
|
||||||
GL15.glMatrixMode(glMatrixMode);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
+1
-1
@@ -26,6 +26,6 @@ public class DependencySetupDoneCheck
|
|||||||
// TODO move to DependencySetup
|
// TODO move to DependencySetup
|
||||||
public static boolean isDone = false;
|
public static boolean isDone = false;
|
||||||
// TODO why is this here and what is its purpose?
|
// TODO why is this here and what is its purpose?
|
||||||
public static Supplier<Boolean> getIsCurrentThreadDistantGeneratorThread = (() -> { return false; });
|
public static Supplier<Boolean> getIsCurrentThreadDistantGeneratorThread = (() -> false);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+34
-47
@@ -23,16 +23,10 @@ import java.nio.FloatBuffer;
|
|||||||
import java.util.function.BiConsumer;
|
import java.util.function.BiConsumer;
|
||||||
import java.util.function.Consumer;
|
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.enums.EDhDirection;
|
||||||
import com.seibel.distanthorizons.core.pos.DhBlockPos;
|
import com.seibel.distanthorizons.core.pos.DhBlockPos;
|
||||||
import com.seibel.distanthorizons.core.pos.DhChunkPos;
|
import com.seibel.distanthorizons.core.pos.DhChunkPos;
|
||||||
import com.seibel.distanthorizons.coreapi.util.math.Mat4f;
|
import com.seibel.distanthorizons.core.util.math.Mat4f;
|
||||||
|
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.core.Direction;
|
import net.minecraft.core.Direction;
|
||||||
@@ -51,10 +45,31 @@ public class McObjectConverter
|
|||||||
{
|
{
|
||||||
return y * 4 + x;
|
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);
|
matrix.store(buffer);
|
||||||
#else
|
#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
|
// 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
|
#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 Direction[] directions;
|
||||||
static final EDhDirection[] lodDirections;
|
static final EDhDirection[] lodDirections;
|
||||||
@@ -99,31 +102,15 @@ public class McObjectConverter
|
|||||||
lodDirections = new EDhDirection[lodDirs.length];
|
lodDirections = new EDhDirection[lodDirs.length];
|
||||||
for (EDhDirection lodDir : lodDirs)
|
for (EDhDirection lodDir : lodDirs)
|
||||||
{
|
{
|
||||||
Direction dir;
|
Direction dir = switch (lodDir.name().toUpperCase()) {
|
||||||
switch (lodDir.name().toUpperCase())
|
case "DOWN" -> Direction.DOWN;
|
||||||
{
|
case "UP" -> Direction.UP;
|
||||||
case "DOWN":
|
case "NORTH" -> Direction.NORTH;
|
||||||
dir = Direction.DOWN;
|
case "SOUTH" -> Direction.SOUTH;
|
||||||
break;
|
case "WEST" -> Direction.WEST;
|
||||||
case "UP":
|
case "EAST" -> Direction.EAST;
|
||||||
dir = Direction.UP;
|
default -> null;
|
||||||
break;
|
};
|
||||||
case "NORTH":
|
|
||||||
dir = Direction.NORTH;
|
|
||||||
break;
|
|
||||||
case "SOUTH":
|
|
||||||
dir = Direction.SOUTH;
|
|
||||||
break;
|
|
||||||
case "WEST":
|
|
||||||
dir = Direction.WEST;
|
|
||||||
break;
|
|
||||||
case "EAST":
|
|
||||||
dir = Direction.EAST;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
dir = null;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dir == null)
|
if (dir == null)
|
||||||
{
|
{
|
||||||
|
|||||||
+1
-1
@@ -59,7 +59,7 @@ public class VersionConstants implements IVersionConstants
|
|||||||
@Override
|
@Override
|
||||||
public String getMinecraftVersion()
|
public String getMinecraftVersion()
|
||||||
{
|
{
|
||||||
#if PRE_MC_1_19_2
|
#if MC_VER < MC_1_19_2
|
||||||
return Minecraft.getInstance().getGame().getVersion().getId();
|
return Minecraft.getInstance().getGame().getVersion().getId();
|
||||||
#else
|
#else
|
||||||
return SharedConstants.getCurrentVersion().getId();
|
return SharedConstants.getCurrentVersion().getId();
|
||||||
|
|||||||
+205
-20
@@ -19,7 +19,11 @@
|
|||||||
|
|
||||||
package com.seibel.distanthorizons.common.wrappers;
|
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.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.BiomeWrapper;
|
||||||
import com.seibel.distanthorizons.common.wrappers.block.BlockStateWrapper;
|
import com.seibel.distanthorizons.common.wrappers.block.BlockStateWrapper;
|
||||||
import com.seibel.distanthorizons.common.wrappers.chunk.ChunkWrapper;
|
import com.seibel.distanthorizons.common.wrappers.chunk.ChunkWrapper;
|
||||||
@@ -28,6 +32,7 @@ import com.seibel.distanthorizons.common.wrappers.world.ServerLevelWrapper;
|
|||||||
import com.seibel.distanthorizons.common.wrappers.worldGeneration.BatchGenerationEnvironment;
|
import com.seibel.distanthorizons.common.wrappers.worldGeneration.BatchGenerationEnvironment;
|
||||||
import com.seibel.distanthorizons.core.level.IDhLevel;
|
import com.seibel.distanthorizons.core.level.IDhLevel;
|
||||||
import com.seibel.distanthorizons.core.level.IDhServerLevel;
|
import com.seibel.distanthorizons.core.level.IDhServerLevel;
|
||||||
|
import com.seibel.distanthorizons.core.util.LodUtil;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.IWrapperFactory;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.IWrapperFactory;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.block.IBlockStateWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.block.IBlockStateWrapper;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.chunk.IChunkWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.chunk.IChunkWrapper;
|
||||||
@@ -35,9 +40,14 @@ import com.seibel.distanthorizons.core.wrapperInterfaces.world.IBiomeWrapper;
|
|||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.worldGeneration.AbstractBatchGenerationEnvironmentWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.worldGeneration.AbstractBatchGenerationEnvironmentWrapper;
|
||||||
import net.minecraft.client.multiplayer.ClientLevel;
|
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.server.level.ServerLevel;
|
||||||
import net.minecraft.world.level.Level;
|
import net.minecraft.world.level.Level;
|
||||||
import net.minecraft.world.level.LevelReader;
|
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 net.minecraft.world.level.chunk.ChunkAccess;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@@ -45,9 +55,6 @@ import java.util.HashSet;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* This handles creating abstract wrapper objects.
|
* This handles creating abstract wrapper objects.
|
||||||
*
|
|
||||||
* @author James Seibel
|
|
||||||
* @version 2022-12-5
|
|
||||||
*/
|
*/
|
||||||
public class WrapperFactory implements IWrapperFactory
|
public class WrapperFactory implements IWrapperFactory
|
||||||
{
|
{
|
||||||
@@ -55,6 +62,9 @@ public class WrapperFactory implements IWrapperFactory
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//==============//
|
||||||
|
// core methods //
|
||||||
|
//==============//
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AbstractBatchGenerationEnvironmentWrapper createBatchGenerator(IDhLevel targetLevel)
|
public AbstractBatchGenerationEnvironmentWrapper createBatchGenerator(IDhLevel targetLevel)
|
||||||
@@ -69,17 +79,56 @@ public class WrapperFactory implements IWrapperFactory
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IDhApiBiomeWrapper getBiomeWrapper(String resourceLocationString, IDhApiLevelWrapper levelWrapper) throws IOException, ClassCastException
|
||||||
|
{
|
||||||
|
if (!(levelWrapper instanceof ILevelWrapper))
|
||||||
|
{
|
||||||
|
throw new ClassCastException("levelWrapper must be returned by DH and of type ["+ILevelWrapper.class.getName()+"].");
|
||||||
|
}
|
||||||
|
|
||||||
|
return BiomeWrapper.deserialize(resourceLocationString, (ILevelWrapper)levelWrapper);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public IDhApiBlockStateWrapper getDefaultBlockStateWrapper(String resourceLocationString, IDhApiLevelWrapper levelWrapper) throws IOException, ClassCastException
|
||||||
|
{
|
||||||
|
if (!(levelWrapper instanceof ILevelWrapper))
|
||||||
|
{
|
||||||
|
throw new ClassCastException("Invalid ["+IDhApiLevelWrapper.class.getSimpleName()+"] value given. Level wrapper object must be one given by the DH API (it can't be a custom implementation), specifically of type ["+ILevelWrapper.class.getName()+"].");
|
||||||
|
}
|
||||||
|
|
||||||
|
return BlockStateWrapper.deserialize(resourceLocationString, (ILevelWrapper)levelWrapper);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IBiomeWrapper deserializeBiomeWrapper(String str, ILevelWrapper levelWrapper) throws IOException { return BiomeWrapper.deserialize(str, levelWrapper); }
|
public IBiomeWrapper deserializeBiomeWrapper(String str, ILevelWrapper levelWrapper) throws IOException { return BiomeWrapper.deserialize(str, levelWrapper); }
|
||||||
|
@Override
|
||||||
|
public IBiomeWrapper getPlainsBiomeWrapper(ILevelWrapper levelWrapper) // TODO is there a way we could get this without the levelWrapper? it isn't necessary but would clean up the code a bit
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return BiomeWrapper.deserialize(BiomeWrapper.PLAINS_RESOURCE_LOCATION_STRING, levelWrapper);
|
||||||
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
throw new LodUtil.AssertFailureException("Unable to parse plains resource string ["+BiomeWrapper.PLAINS_RESOURCE_LOCATION_STRING+"], error:\n " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IBlockStateWrapper deserializeBlockStateWrapper(String str, ILevelWrapper levelWrapper) throws IOException { return BlockStateWrapper.deserialize(str, levelWrapper); }
|
public IBlockStateWrapper deserializeBlockStateWrapper(String str, ILevelWrapper levelWrapper) throws IOException { return BlockStateWrapper.deserialize(str, levelWrapper); }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IBlockStateWrapper getAirBlockStateWrapper() { return BlockStateWrapper.AIR; }
|
public IBlockStateWrapper getAirBlockStateWrapper() { return BlockStateWrapper.AIR; }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public HashSet<IBlockStateWrapper> getRendererIgnoredBlocks(ILevelWrapper levelWrapper) { return BlockStateWrapper.getRendererIgnoredBlocks(levelWrapper); }
|
public HashSet<IBlockStateWrapper> getRendererIgnoredBlocks(ILevelWrapper levelWrapper) { return BlockStateWrapper.getRendererIgnoredBlocks(levelWrapper); }
|
||||||
|
@Override
|
||||||
|
public HashSet<IBlockStateWrapper> getRendererIgnoredCaveBlocks(ILevelWrapper levelWrapper) { return BlockStateWrapper.getRendererIgnoredCaveBlocks(levelWrapper); }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void resetRendererIgnoredCaveBlocks() { BlockStateWrapper.clearRendererIgnoredCaveBlocks(); }
|
||||||
|
@Override
|
||||||
|
public void resetRendererIgnoredBlocksSet() { BlockStateWrapper.clearRendererIgnoredBlocks(); }
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -106,26 +155,23 @@ public class WrapperFactory implements IWrapperFactory
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// MC 1.16, 1.18, 1.19, 1.20
|
#if MC_VER <= MC_1_21
|
||||||
#if POST_MC_1_17_1 || MC_1_16_5
|
|
||||||
else if (objectArray.length == 2)
|
else if (objectArray.length == 2)
|
||||||
{
|
{
|
||||||
// correct number of parameters from the API
|
// correct number of parameters from the API
|
||||||
|
|
||||||
// chunk
|
// chunk
|
||||||
if (!(objectArray[0] instanceof ChunkAccess))
|
if (!(objectArray[0] instanceof ChunkAccess chunk))
|
||||||
{
|
{
|
||||||
throw new ClassCastException(createChunkWrapperErrorMessage(objectArray));
|
throw new ClassCastException(createChunkWrapperErrorMessage(objectArray));
|
||||||
}
|
}
|
||||||
ChunkAccess chunk = (ChunkAccess) objectArray[0];
|
|
||||||
|
|
||||||
// level / light source
|
// level / light source
|
||||||
if (!(objectArray[1] instanceof Level))
|
if (!(objectArray[1] instanceof Level level))
|
||||||
{
|
{
|
||||||
throw new ClassCastException(createChunkWrapperErrorMessage(objectArray));
|
throw new ClassCastException(createChunkWrapperErrorMessage(objectArray));
|
||||||
}
|
}
|
||||||
// the level is needed for the DH level wrapper...
|
// the level is needed for the DH level wrapper...
|
||||||
Level level = (Level) objectArray[1];
|
|
||||||
// ...the LevelReader is needed for chunk lighting
|
// ...the LevelReader is needed for chunk lighting
|
||||||
LevelReader lightSource = level;
|
LevelReader lightSource = level;
|
||||||
|
|
||||||
@@ -156,7 +202,7 @@ public class WrapperFactory implements IWrapperFactory
|
|||||||
#else
|
#else
|
||||||
// Intentional compiler error to bring attention to the missing wrapper function.
|
// 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
|
// 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
|
// 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
|
// on what other locations also need to be updated, the DhAPI specifically needs to
|
||||||
@@ -170,25 +216,164 @@ public class WrapperFactory implements IWrapperFactory
|
|||||||
*/
|
*/
|
||||||
private static String createChunkWrapperErrorMessage(Object[] objectArray)
|
private static String createChunkWrapperErrorMessage(Object[] objectArray)
|
||||||
{
|
{
|
||||||
StringBuilder message = new StringBuilder(
|
String[] expectedClassNames;
|
||||||
"Chunk wrapper creation failed. \n" +
|
|
||||||
"Expected parameters: \n");
|
|
||||||
|
|
||||||
// MC 1.16, 1.18, 1.19, 1.20
|
#if MC_VER <= MC_1_21
|
||||||
#if POST_MC_1_17_1 || MC_1_16_5
|
expectedClassNames = new String[]
|
||||||
message.append("[" + ChunkAccess.class.getName() + "], \n");
|
{
|
||||||
message.append("[" + ServerLevel.class.getName() + "] or [" + ClientLevel.class.getName() + "]. \n");
|
ChunkAccess.class.getName(),
|
||||||
|
ServerLevel.class.getName() + "] or [" + ClientLevel.class.getName()
|
||||||
|
};
|
||||||
#else
|
#else
|
||||||
// See preprocessor comment in createChunkWrapper() for full documentation
|
// See preprocessor comment in createChunkWrapper() for full documentation
|
||||||
not implemented for this version of Minecraft!
|
not implemented for this version of Minecraft!
|
||||||
#endif
|
#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 coreLevelWrapper))
|
||||||
|
{
|
||||||
|
throw new ClassCastException("Invalid ["+IDhApiLevelWrapper.class.getSimpleName()+"] value given. Level wrapper object must be one given by the DH API (it can't be a custom implementation), specifically of type ["+ILevelWrapper.class.getName()+"].");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#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_21
|
||||||
|
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_21
|
||||||
|
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 coreLevelWrapper))
|
||||||
|
{
|
||||||
|
throw new ClassCastException("Invalid ["+IDhApiLevelWrapper.class.getSimpleName()+"] value given. Level wrapper object must be one given by the DH API (it can't be a custom implementation), specifically of type ["+ILevelWrapper.class.getName()+"].");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#if MC_VER <= MC_1_21
|
||||||
|
if (objectArray.length != 1)
|
||||||
|
{
|
||||||
|
throw new ClassCastException(createBlockStateWrapperErrorMessage(objectArray));
|
||||||
|
}
|
||||||
|
if (!(objectArray[0] instanceof BlockState blockState))
|
||||||
|
{
|
||||||
|
throw new ClassCastException(createBlockStateWrapperErrorMessage(objectArray));
|
||||||
|
}
|
||||||
|
|
||||||
|
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_21
|
||||||
|
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)
|
if (objectArray.length != 0)
|
||||||
{
|
{
|
||||||
message.append("Given parameters: ");
|
message.append("Given parameters: ");
|
||||||
for (Object obj : objectArray)
|
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
|
else
|
||||||
@@ -196,8 +381,8 @@ public class WrapperFactory implements IWrapperFactory
|
|||||||
message.append(" No parameters given.");
|
message.append(" No parameters given.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return message.toString();
|
return message.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+109
-44
@@ -32,19 +32,9 @@ import org.apache.logging.log4j.Logger;
|
|||||||
|
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IBiomeWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IBiomeWrapper;
|
||||||
|
|
||||||
import net.minecraft.client.Minecraft;
|
#if MC_VER == MC_1_16_5 || MC_VER == MC_1_17_1
|
||||||
#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
|
|
||||||
import net.minecraft.core.Registry;
|
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.Holder;
|
||||||
import net.minecraft.core.Registry;
|
import net.minecraft.core.Registry;
|
||||||
import net.minecraft.core.RegistryAccess;
|
import net.minecraft.core.RegistryAccess;
|
||||||
@@ -56,7 +46,7 @@ import net.minecraft.core.registries.Registries;
|
|||||||
|
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
import net.minecraft.world.level.biome.Biome;
|
import net.minecraft.world.level.biome.Biome;
|
||||||
#if !PRE_MC_1_18_2
|
#if MC_VER >= MC_1_18_2
|
||||||
import net.minecraft.world.level.biome.Biomes;
|
import net.minecraft.world.level.biome.Biomes;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -64,32 +54,46 @@ import net.minecraft.world.level.biome.Biomes;
|
|||||||
/** This class wraps the minecraft BlockPos.Mutable (and BlockPos) class */
|
/** This class wraps the minecraft BlockPos.Mutable (and BlockPos) class */
|
||||||
public class BiomeWrapper implements IBiomeWrapper
|
public class BiomeWrapper implements IBiomeWrapper
|
||||||
{
|
{
|
||||||
|
// must be defined before AIR, otherwise a null pointer will be thrown
|
||||||
private static final Logger LOGGER = LogManager.getLogger();
|
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<>();
|
public static final ConcurrentMap<Biome, BiomeWrapper> WRAPPER_BY_BIOME = new ConcurrentHashMap<>();
|
||||||
#else
|
#else
|
||||||
public static final ConcurrentMap<Holder<Biome>, BiomeWrapper> WRAPPER_BY_BIOME = new ConcurrentHashMap<>();
|
public static final ConcurrentMap<Holder<Biome>, BiomeWrapper> WRAPPER_BY_BIOME = new ConcurrentHashMap<>();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
public static final String EMPTY_STRING = "EMPTY";
|
public static final ConcurrentHashMap<String, BiomeWrapper> WRAPPER_BY_RESOURCE_LOCATION = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
public static final String EMPTY_BIOME_STRING = "EMPTY";
|
||||||
public static final BiomeWrapper EMPTY_WRAPPER = new BiomeWrapper(null, null);
|
public static final BiomeWrapper EMPTY_WRAPPER = new BiomeWrapper(null, null);
|
||||||
|
|
||||||
|
public static final String PLAINS_RESOURCE_LOCATION_STRING = "minecraft:plains";
|
||||||
|
|
||||||
/** keep track of broken biomes so we don't log every time */
|
/** 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 //
|
// properties //
|
||||||
|
|
||||||
#if PRE_MC_1_18_2
|
#if MC_VER < MC_1_18_2
|
||||||
public final Biome biome;
|
public final Biome biome;
|
||||||
#else
|
#else
|
||||||
public final Holder<Biome> biome;
|
public final Holder<Biome> biome;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/** technically final, but since it requires a method call to generate it can't be marked as such */
|
/** technically final, but since it requires a method call to generate it can't be marked as such */
|
||||||
private String serialString = null;
|
private String serialString;
|
||||||
|
private final int hashCode;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -97,7 +101,7 @@ public class BiomeWrapper implements IBiomeWrapper
|
|||||||
// constructors //
|
// 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)
|
if (biome == null)
|
||||||
{
|
{
|
||||||
@@ -116,12 +120,21 @@ public class BiomeWrapper implements IBiomeWrapper
|
|||||||
return newWrapper;
|
return newWrapper;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
private BiomeWrapper(#if MC_VER < MC_1_18_2 Biome #else Holder<Biome> #endif biome, ILevelWrapper levelWrapper)
|
||||||
private BiomeWrapper(#if PRE_MC_1_18_2 Biome #else Holder<Biome> #endif biome, ILevelWrapper levelWrapper)
|
|
||||||
{
|
{
|
||||||
this.biome = biome;
|
this.biome = biome;
|
||||||
this.serialString = this.serialize(levelWrapper);
|
this.serialString = this.serialize(levelWrapper);
|
||||||
LOGGER.trace("Created BiomeWrapper ["+this.serialString+"] for ["+biome+"]");
|
this.hashCode = Objects.hash(this.serialString);
|
||||||
|
|
||||||
|
//LOGGER.trace("Created BiomeWrapper ["+this.serialString+"] for ["+biome+"]");
|
||||||
|
}
|
||||||
|
|
||||||
|
/** should only be used to create {@link BiomeWrapper#EMPTY_WRAPPER} */
|
||||||
|
private BiomeWrapper()
|
||||||
|
{
|
||||||
|
this.biome = null;
|
||||||
|
this.serialString = EMPTY_BIOME_STRING;
|
||||||
|
this.hashCode = Objects.hash(this.serialString);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -135,10 +148,10 @@ public class BiomeWrapper implements IBiomeWrapper
|
|||||||
{
|
{
|
||||||
if (this == EMPTY_WRAPPER)
|
if (this == EMPTY_WRAPPER)
|
||||||
{
|
{
|
||||||
return EMPTY_STRING;
|
return EMPTY_BIOME_STRING;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if PRE_MC_1_18_2
|
#if MC_VER < MC_1_18_2
|
||||||
return biome.toString();
|
return biome.toString();
|
||||||
#else
|
#else
|
||||||
return this.biome.unwrapKey().orElse(Biomes.THE_VOID).registry().toString();
|
return this.biome.unwrapKey().orElse(Biomes.THE_VOID).registry().toString();
|
||||||
@@ -163,7 +176,7 @@ public class BiomeWrapper implements IBiomeWrapper
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() { return Objects.hash(this.getSerialString()); }
|
public int hashCode() { return this.hashCode; }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getSerialString() { return this.serialString; }
|
public String getSerialString() { return this.serialString; }
|
||||||
@@ -182,20 +195,36 @@ public class BiomeWrapper implements IBiomeWrapper
|
|||||||
|
|
||||||
public String serialize(ILevelWrapper levelWrapper)
|
public String serialize(ILevelWrapper levelWrapper)
|
||||||
{
|
{
|
||||||
if (levelWrapper == null)
|
if (this.biome == null)
|
||||||
{
|
{
|
||||||
return EMPTY_STRING;
|
return EMPTY_BIOME_STRING;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (this.serialString == null)
|
|
||||||
|
// we can't generate a serial string if the level is null
|
||||||
|
if (levelWrapper == null)
|
||||||
{
|
{
|
||||||
net.minecraft.core.RegistryAccess registryAccess = Minecraft.getInstance().level.registryAccess();
|
if (!emptyLevelSerializeFailLogged)
|
||||||
|
{
|
||||||
|
emptyLevelSerializeFailLogged = true;
|
||||||
|
LOGGER.warn("Unable to serialize biome: [" + this.biome + "] because the passed in level wrapper is null. Future errors of this type won't be logged.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return EMPTY_BIOME_STRING;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// generate the serial string //
|
||||||
|
|
||||||
|
Level level = (Level)levelWrapper.getWrappedMcObject();
|
||||||
|
net.minecraft.core.RegistryAccess registryAccess = level.registryAccess();
|
||||||
|
|
||||||
ResourceLocation resourceLocation;
|
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 = registryAccess.registryOrThrow(Registry.BIOME_REGISTRY).getKey(this.biome);
|
resourceLocation = registryAccess.registryOrThrow(Registry.BIOME_REGISTRY).getKey(this.biome);
|
||||||
#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.BIOME_REGISTRY).getKey(this.biome.value());
|
resourceLocation = registryAccess.registryOrThrow(Registry.BIOME_REGISTRY).getKey(this.biome.value());
|
||||||
#else
|
#else
|
||||||
resourceLocation = registryAccess.registryOrThrow(Registries.BIOME).getKey(this.biome.value());
|
resourceLocation = registryAccess.registryOrThrow(Registries.BIOME).getKey(this.biome.value());
|
||||||
@@ -204,7 +233,7 @@ public class BiomeWrapper implements IBiomeWrapper
|
|||||||
if (resourceLocation == null)
|
if (resourceLocation == null)
|
||||||
{
|
{
|
||||||
String biomeName;
|
String biomeName;
|
||||||
#if MC_1_16_5 || MC_1_17_1
|
#if MC_VER == MC_1_16_5 || MC_VER == MC_1_17_1
|
||||||
biomeName = this.biome.toString();
|
biomeName = this.biome.toString();
|
||||||
#else
|
#else
|
||||||
biomeName = this.biome.value().toString();
|
biomeName = this.biome.value().toString();
|
||||||
@@ -218,45 +247,74 @@ public class BiomeWrapper implements IBiomeWrapper
|
|||||||
{
|
{
|
||||||
this.serialString = resourceLocation.getNamespace() + ":" + resourceLocation.getPath();
|
this.serialString = resourceLocation.getNamespace() + ":" + resourceLocation.getPath();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return this.serialString;
|
return this.serialString;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO would it be worth while to cache these objects in a ConcurrentHashMap<string, IBiomeWrapper>?
|
||||||
public static IBiomeWrapper deserialize(String resourceLocationString, ILevelWrapper levelWrapper) throws IOException
|
public static IBiomeWrapper deserialize(String resourceLocationString, ILevelWrapper levelWrapper) throws IOException
|
||||||
{
|
{
|
||||||
if (resourceLocationString.equals(EMPTY_STRING))
|
// we need the final string for the concurrent hash map later
|
||||||
|
final String finalResourceStateString = resourceLocationString;
|
||||||
|
|
||||||
|
if (resourceLocationString.equals(EMPTY_BIOME_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_BIOME_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;
|
return EMPTY_WRAPPER;
|
||||||
}
|
}
|
||||||
else if (resourceLocationString.trim().isEmpty() || resourceLocationString.equals(""))
|
else if (resourceLocationString.trim().isEmpty() || resourceLocationString.isEmpty())
|
||||||
{
|
{
|
||||||
LOGGER.warn("Null biome string deserialized.");
|
LOGGER.warn("Null biome string deserialized.");
|
||||||
return EMPTY_WRAPPER;
|
return EMPTY_WRAPPER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (WRAPPER_BY_RESOURCE_LOCATION.containsKey(finalResourceStateString))
|
||||||
|
{
|
||||||
|
return WRAPPER_BY_RESOURCE_LOCATION.get(finalResourceStateString);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// if no wrapper is found, default to the empty wrapper
|
||||||
|
BiomeWrapper foundWrapper = EMPTY_WRAPPER;
|
||||||
|
try
|
||||||
|
{
|
||||||
// parse the resource location
|
// parse the resource location
|
||||||
int separatorIndex = resourceLocationString.indexOf(":");
|
int separatorIndex = resourceLocationString.indexOf(":");
|
||||||
if (separatorIndex == -1)
|
if (separatorIndex == -1)
|
||||||
{
|
{
|
||||||
throw new IOException("Unable to parse resource location string: [" + resourceLocationString + "].");
|
throw new IOException("Unable to parse resource location string: [" + resourceLocationString + "].");
|
||||||
}
|
}
|
||||||
ResourceLocation resourceLocation = new ResourceLocation(resourceLocationString.substring(0, separatorIndex), resourceLocationString.substring(separatorIndex + 1));
|
|
||||||
|
ResourceLocation resourceLocation;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
#if MC_VER < MC_1_21
|
||||||
|
resourceLocation = new ResourceLocation(resourceLocationString.substring(0, separatorIndex), resourceLocationString.substring(separatorIndex + 1));
|
||||||
|
#else
|
||||||
|
resourceLocation = ResourceLocation.fromNamespaceAndPath(resourceLocationString.substring(0, separatorIndex), resourceLocationString.substring(separatorIndex + 1));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
throw new IOException("No Resource Location found for the string: [" + resourceLocationString + "] Error: [" + e.getMessage() + "].");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Level level = (Level)levelWrapper.getWrappedMcObject();
|
Level level = (Level) levelWrapper.getWrappedMcObject();
|
||||||
net.minecraft.core.RegistryAccess registryAccess = level.registryAccess();
|
net.minecraft.core.RegistryAccess registryAccess = level.registryAccess();
|
||||||
|
|
||||||
boolean success;
|
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);
|
Biome biome = registryAccess.registryOrThrow(Registry.BIOME_REGISTRY).get(resourceLocation);
|
||||||
success = (biome != null);
|
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);
|
Biome unwrappedBiome = registryAccess.registryOrThrow(Registry.BIOME_REGISTRY).get(resourceLocation);
|
||||||
success = (unwrappedBiome != null);
|
success = (unwrappedBiome != null);
|
||||||
Holder<Biome> biome = new Holder.Direct<>(unwrappedBiome);
|
Holder<Biome> biome = new Holder.Direct<>(unwrappedBiome);
|
||||||
@@ -270,19 +328,26 @@ public class BiomeWrapper implements IBiomeWrapper
|
|||||||
|
|
||||||
if (!success)
|
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 + "]");
|
LOGGER.warn("Unable to deserialize biome from string: [" + resourceLocationString + "]");
|
||||||
}
|
}
|
||||||
return EMPTY_WRAPPER;
|
return EMPTY_WRAPPER;
|
||||||
}
|
}
|
||||||
|
|
||||||
return getBiomeWrapper(biome, levelWrapper);
|
|
||||||
|
foundWrapper = (BiomeWrapper) getBiomeWrapper(biome, levelWrapper);
|
||||||
|
return foundWrapper;
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
throw new IOException("Failed to deserialize the string [" + resourceLocationString + "] into a BiomeWrapper: " + e.getMessage(), e);
|
throw new IOException("Failed to deserialize the string [" + finalResourceStateString + "] into a BiomeWrapper: " + e.getMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
WRAPPER_BY_RESOURCE_LOCATION.putIfAbsent(finalResourceStateString, foundWrapper);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+316
-39
@@ -19,24 +19,35 @@
|
|||||||
|
|
||||||
package com.seibel.distanthorizons.common.wrappers.block;
|
package com.seibel.distanthorizons.common.wrappers.block;
|
||||||
|
|
||||||
|
import com.seibel.distanthorizons.api.enums.rendering.EDhApiBlockMaterial;
|
||||||
|
import com.seibel.distanthorizons.core.config.Config;
|
||||||
|
import com.seibel.distanthorizons.core.config.types.ConfigEntry;
|
||||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||||
|
import com.seibel.distanthorizons.core.util.ColorUtil;
|
||||||
|
import com.seibel.distanthorizons.core.util.LodUtil;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.block.IBlockStateWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.block.IBlockStateWrapper;
|
||||||
|
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
import net.minecraft.tags.BlockTags;
|
||||||
import net.minecraft.world.level.block.Block;
|
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 net.minecraft.world.level.block.state.BlockState;
|
||||||
|
import net.minecraft.world.level.block.state.properties.Property;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.List;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
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.Registry;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.world.level.EmptyBlockGetter;
|
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.client.Minecraft;
|
||||||
import net.minecraft.world.level.Level;
|
import net.minecraft.world.level.Level;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
@@ -62,13 +73,15 @@ public class BlockStateWrapper implements IBlockStateWrapper
|
|||||||
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
|
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
|
||||||
|
|
||||||
public static final ConcurrentHashMap<BlockState, BlockStateWrapper> WRAPPER_BY_BLOCK_STATE = new ConcurrentHashMap<>();
|
public static final ConcurrentHashMap<BlockState, BlockStateWrapper> WRAPPER_BY_BLOCK_STATE = new ConcurrentHashMap<>();
|
||||||
|
public static final ConcurrentHashMap<String, BlockStateWrapper> WRAPPER_BY_RESOURCE_LOCATION = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
public static final String AIR_STRING = "AIR";
|
public static final String AIR_STRING = "AIR";
|
||||||
public static final BlockStateWrapper AIR = new BlockStateWrapper(null, null);
|
public static final BlockStateWrapper AIR = new BlockStateWrapper(null, null);
|
||||||
|
|
||||||
// TODO: Make this changeable through the config
|
public static final String DIRT_RESOURCE_LOCATION_STRING = "minecraft:dirt";
|
||||||
public static final String[] RENDERER_IGNORED_BLOCKS_RESOURCE_LOCATIONS = { AIR_STRING, "minecraft:barrier", "minecraft:structure_void", "minecraft:light", "minecraft:tripwire" };
|
|
||||||
public static HashSet<IBlockStateWrapper> rendererIgnoredBlocks = null;
|
public static HashSet<IBlockStateWrapper> rendererIgnoredBlocks = null;
|
||||||
|
public static HashSet<IBlockStateWrapper> rendererIgnoredCaveBlocks = null;
|
||||||
|
|
||||||
/** keep track of broken blocks so we don't log every time */
|
/** keep track of broken blocks so we don't log every time */
|
||||||
private static final HashSet<ResourceLocation> BrokenResourceLocations = new HashSet<>();
|
private static final HashSet<ResourceLocation> BrokenResourceLocations = new HashSet<>();
|
||||||
@@ -80,11 +93,19 @@ public class BlockStateWrapper implements IBlockStateWrapper
|
|||||||
public final BlockState blockState;
|
public final BlockState blockState;
|
||||||
/** technically final, but since it requires a method call to generate it can't be marked as such */
|
/** technically final, but since it requires a method call to generate it can't be marked as such */
|
||||||
private String serialString;
|
private String serialString;
|
||||||
|
private final int hashCode;
|
||||||
/**
|
/**
|
||||||
* Cached opacity value, -1 if not populated. <br>
|
* Cached opacity value, -1 if not populated. <br>
|
||||||
* Should be between {@link IBlockStateWrapper#FULLY_OPAQUE} and {@link IBlockStateWrapper#FULLY_OPAQUE}
|
* Should be between {@link LodUtil#BLOCK_FULLY_OPAQUE} and {@link LodUtil#BLOCK_FULLY_OPAQUE}
|
||||||
*/
|
*/
|
||||||
private int opacity = -1;
|
private int opacity = -1;
|
||||||
|
/** used by the Iris shader mod to determine how each LOD should be rendered */
|
||||||
|
private byte blockMaterialId = 0;
|
||||||
|
|
||||||
|
private final boolean isBeaconBlock;
|
||||||
|
private final boolean isBeaconBaseBlock;
|
||||||
|
private final boolean isGlassBlock;
|
||||||
|
private final Color mapColor;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -116,14 +137,47 @@ public class BlockStateWrapper implements IBlockStateWrapper
|
|||||||
{
|
{
|
||||||
this.blockState = blockState;
|
this.blockState = blockState;
|
||||||
this.serialString = this.serialize(levelWrapper);
|
this.serialString = this.serialize(levelWrapper);
|
||||||
LOGGER.trace("Created BlockStateWrapper ["+this.serialString+"] for ["+blockState+"]");
|
this.hashCode = Objects.hash(this.serialString);
|
||||||
|
this.blockMaterialId = this.calculateEDhApiBlockMaterialId().index;
|
||||||
|
|
||||||
|
String lowercaseSerial = this.serialString.toLowerCase();
|
||||||
|
boolean isBeaconBaseBlock = false;
|
||||||
|
for (int i = 0; i < LodUtil.BEACON_BASE_BLOCK_NAME_LIST.size(); i++)
|
||||||
|
{
|
||||||
|
String baseBlockName = LodUtil.BEACON_BASE_BLOCK_NAME_LIST.get(i);
|
||||||
|
if (lowercaseSerial.contains(baseBlockName))
|
||||||
|
{
|
||||||
|
isBeaconBaseBlock = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.isBeaconBaseBlock = isBeaconBaseBlock;
|
||||||
|
this.isBeaconBlock = lowercaseSerial.contains("minecraft:beacon");
|
||||||
|
this.isGlassBlock = lowercaseSerial.contains("glass");
|
||||||
|
|
||||||
|
int mcColor = 0;
|
||||||
|
if (this.blockState != null)
|
||||||
|
{
|
||||||
|
#if MC_VER < MC_1_20_1
|
||||||
|
mcColor = this.blockState.getMaterial().getColor().col;
|
||||||
|
#else
|
||||||
|
mcColor = this.blockState.getMapColor(EmptyBlockGetter.INSTANCE, BlockPos.ZERO).col;
|
||||||
|
#endif
|
||||||
|
this.mapColor = ColorUtil.toColorObjRGB(mcColor);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this.mapColor = new Color(0,0,0,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
//LOGGER.trace("Created BlockStateWrapper ["+this.serialString+"] for ["+blockState+"] with material ID ["+this.EDhApiBlockMaterialId+"]");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//================//
|
//====================//
|
||||||
// helper methods //
|
// LodBuilder methods //
|
||||||
//================//
|
//====================//
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Requires a {@link ILevelWrapper} since {@link BlockStateWrapper#deserialize(String,ILevelWrapper)} also requires one.
|
* Requires a {@link ILevelWrapper} since {@link BlockStateWrapper#deserialize(String,ILevelWrapper)} also requires one.
|
||||||
@@ -137,37 +191,104 @@ public class BlockStateWrapper implements IBlockStateWrapper
|
|||||||
return rendererIgnoredBlocks;
|
return rendererIgnoredBlocks;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HashSet<String> baseIgnoredBlock = new HashSet<>();
|
||||||
|
baseIgnoredBlock.add(AIR_STRING);
|
||||||
|
rendererIgnoredBlocks = getBlockWrappers(Config.Client.Advanced.LodBuilding.ignoredRenderBlockCsv, baseIgnoredBlock, levelWrapper);
|
||||||
|
return rendererIgnoredBlocks;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Requires a {@link ILevelWrapper} since {@link BlockStateWrapper#deserialize(String,ILevelWrapper)} also requires one.
|
||||||
|
* This way the method won't accidentally be called before the deserialization can be completed.
|
||||||
|
*/
|
||||||
|
public static HashSet<IBlockStateWrapper> getRendererIgnoredCaveBlocks(ILevelWrapper levelWrapper)
|
||||||
|
{
|
||||||
|
// use the cached version if possible
|
||||||
|
if (rendererIgnoredCaveBlocks != null)
|
||||||
|
{
|
||||||
|
return rendererIgnoredCaveBlocks;
|
||||||
|
}
|
||||||
|
|
||||||
|
HashSet<String> baseIgnoredBlock = new HashSet<>();
|
||||||
|
baseIgnoredBlock.add(AIR_STRING);
|
||||||
|
rendererIgnoredCaveBlocks = getBlockWrappers(Config.Client.Advanced.LodBuilding.ignoredRenderCaveBlockCsv, baseIgnoredBlock, levelWrapper);
|
||||||
|
return rendererIgnoredCaveBlocks;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void clearRendererIgnoredBlocks() { rendererIgnoredBlocks = null; }
|
||||||
|
public static void clearRendererIgnoredCaveBlocks() { rendererIgnoredCaveBlocks = null; }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// lod builder helpers //
|
||||||
|
|
||||||
|
private static HashSet<IBlockStateWrapper> getBlockWrappers(ConfigEntry<String> config, HashSet<String> baseResourceLocations, ILevelWrapper levelWrapper)
|
||||||
|
{
|
||||||
|
// get the base blocks
|
||||||
|
HashSet<String> blockStringList = new HashSet<>();
|
||||||
|
if (baseResourceLocations != null)
|
||||||
|
{
|
||||||
|
blockStringList.addAll(baseResourceLocations);
|
||||||
|
}
|
||||||
|
|
||||||
|
// get the config blocks
|
||||||
|
String ignoreBlockCsv = config.get();
|
||||||
|
if (ignoreBlockCsv != null)
|
||||||
|
{
|
||||||
|
blockStringList.addAll(List.of(ignoreBlockCsv.split(",")));
|
||||||
|
}
|
||||||
|
|
||||||
|
return getBlockWrappers(blockStringList, levelWrapper);
|
||||||
|
}
|
||||||
|
private static HashSet<IBlockStateWrapper> getBlockWrappers(HashSet<String> blockResourceLocationSet, ILevelWrapper levelWrapper)
|
||||||
|
{
|
||||||
// deserialize each of the given resource locations
|
// deserialize each of the given resource locations
|
||||||
HashSet<IBlockStateWrapper> blockStateWrappers = new HashSet<>();
|
HashSet<IBlockStateWrapper> blockStateWrappers = new HashSet<>();
|
||||||
for (String blockResourceLocation : RENDERER_IGNORED_BLOCKS_RESOURCE_LOCATIONS)
|
for (String blockResourceLocation : blockResourceLocationSet)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
BlockStateWrapper DefaultBlockStateToIgnore = (BlockStateWrapper) deserialize(blockResourceLocation, levelWrapper);
|
if (blockResourceLocation == null)
|
||||||
blockStateWrappers.add(DefaultBlockStateToIgnore);
|
{
|
||||||
|
// shouldn't happen, but just in case
|
||||||
if (DefaultBlockStateToIgnore == AIR)
|
continue;
|
||||||
|
}
|
||||||
|
String cleanedResourceLocation = blockResourceLocation.trim();
|
||||||
|
if (cleanedResourceLocation.length() == 0)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BlockStateWrapper defaultBlockStateToIgnore = (BlockStateWrapper) deserialize(cleanedResourceLocation, levelWrapper);
|
||||||
|
blockStateWrappers.add(defaultBlockStateToIgnore);
|
||||||
|
|
||||||
|
if (defaultBlockStateToIgnore != AIR)
|
||||||
|
{
|
||||||
// add all possible blockstates (to account for light blocks with different light values and such)
|
// add all possible blockstates (to account for light blocks with different light values and such)
|
||||||
List<BlockState> blockStatesToIgnore = DefaultBlockStateToIgnore.blockState.getBlock().getStateDefinition().getPossibleStates();
|
List<BlockState> blockStatesToIgnore = defaultBlockStateToIgnore.blockState.getBlock().getStateDefinition().getPossibleStates();
|
||||||
for (BlockState blockState : blockStatesToIgnore)
|
for (BlockState blockState : blockStatesToIgnore)
|
||||||
{
|
{
|
||||||
BlockStateWrapper newBlockToIgnore = BlockStateWrapper.fromBlockState(blockState, levelWrapper);
|
BlockStateWrapper newBlockToIgnore = BlockStateWrapper.fromBlockState(blockState, levelWrapper);
|
||||||
blockStateWrappers.add(newBlockToIgnore);
|
blockStateWrappers.add(newBlockToIgnore);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// air is a special case so it must be handled separately
|
||||||
|
blockStateWrappers.add(AIR);
|
||||||
|
}
|
||||||
|
}
|
||||||
catch (IOException e)
|
catch (IOException e)
|
||||||
{
|
{
|
||||||
LOGGER.warn("Unable to deserialize rendererIgnoredBlock with the resource location: ["+blockResourceLocation+"]. Error: "+e.getMessage(), e);
|
LOGGER.warn("Unable to deserialize block with the resource location: ["+blockResourceLocation+"]. Error: "+e.getMessage(), e);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
LOGGER.warn("Unexpected error deserializing block with the resource location: ["+blockResourceLocation+"]. Error: "+e.getMessage(), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rendererIgnoredBlocks = blockStateWrappers;
|
return blockStateWrappers;
|
||||||
return rendererIgnoredBlocks;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -190,23 +311,23 @@ public class BlockStateWrapper implements IBlockStateWrapper
|
|||||||
int opacity;
|
int opacity;
|
||||||
if (this.isAir())
|
if (this.isAir())
|
||||||
{
|
{
|
||||||
opacity = FULLY_TRANSPARENT;
|
opacity = LodUtil.BLOCK_FULLY_TRANSPARENT;
|
||||||
}
|
}
|
||||||
else if (this.isLiquid() && !this.blockState.canOcclude())
|
else if (this.isLiquid() && !this.blockState.canOcclude())
|
||||||
{
|
{
|
||||||
// probably not a waterlogged block (which should block light entirely)
|
// probably not a waterlogged block (which should block light entirely)
|
||||||
|
|
||||||
// +1 to indicate that the block is translucent (in between transparent and opaque)
|
// +1 to indicate that the block is translucent (in between transparent and opaque)
|
||||||
opacity = FULLY_TRANSPARENT + 1;
|
opacity = LodUtil.BLOCK_FULLY_TRANSPARENT + 1;
|
||||||
}
|
}
|
||||||
else if (this.blockState.propagatesSkylightDown(EmptyBlockGetter.INSTANCE, BlockPos.ZERO))
|
else if (this.blockState.propagatesSkylightDown(EmptyBlockGetter.INSTANCE, BlockPos.ZERO))
|
||||||
{
|
{
|
||||||
opacity = FULLY_TRANSPARENT;
|
opacity = LodUtil.BLOCK_FULLY_TRANSPARENT;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// default for all other blocks
|
// default for all other blocks
|
||||||
opacity = FULLY_OPAQUE;
|
opacity = LodUtil.BLOCK_FULLY_OPAQUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -239,7 +360,7 @@ public class BlockStateWrapper implements IBlockStateWrapper
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() { return Objects.hash(this.getSerialString()); }
|
public int hashCode() { return this.hashCode; }
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -252,7 +373,7 @@ public class BlockStateWrapper implements IBlockStateWrapper
|
|||||||
@Override
|
@Override
|
||||||
public boolean isSolid()
|
public boolean isSolid()
|
||||||
{
|
{
|
||||||
#if PRE_MC_1_20_1
|
#if MC_VER < MC_1_20_1
|
||||||
return this.blockState.getMaterial().isSolid();
|
return this.blockState.getMaterial().isSolid();
|
||||||
#else
|
#else
|
||||||
return !this.blockState.getCollisionShape(EmptyBlockGetter.INSTANCE, BlockPos.ZERO).isEmpty();
|
return !this.blockState.getCollisionShape(EmptyBlockGetter.INSTANCE, BlockPos.ZERO).isEmpty();
|
||||||
@@ -267,13 +388,26 @@ public class BlockStateWrapper implements IBlockStateWrapper
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if PRE_MC_1_20_1
|
#if MC_VER < MC_1_20_1
|
||||||
return this.blockState.getMaterial().isLiquid() || !this.blockState.getFluidState().isEmpty();
|
return this.blockState.getMaterial().isLiquid() || !this.blockState.getFluidState().isEmpty();
|
||||||
#else
|
#else
|
||||||
return !this.blockState.getFluidState().isEmpty();
|
return !this.blockState.getFluidState().isEmpty();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isBeaconBlock() { return this.isBeaconBlock; }
|
||||||
|
@Override
|
||||||
|
public boolean isBeaconBaseBlock() { return this.isBeaconBaseBlock; }
|
||||||
|
@Override
|
||||||
|
public boolean isGlassBlock() { return this.isGlassBlock; }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Color getMapColor() { return this.mapColor; }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte getMaterialId() { return this.blockMaterialId; }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() { return this.getSerialString(); }
|
public String toString() { return this.getSerialString(); }
|
||||||
|
|
||||||
@@ -293,15 +427,15 @@ public class BlockStateWrapper implements IBlockStateWrapper
|
|||||||
|
|
||||||
|
|
||||||
// older versions of MC have a static registry
|
// 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();
|
Level level = (Level)levelWrapper.getWrappedMcObject();
|
||||||
net.minecraft.core.RegistryAccess registryAccess = level.registryAccess();
|
net.minecraft.core.RegistryAccess registryAccess = level.registryAccess();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ResourceLocation resourceLocation;
|
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());
|
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());
|
resourceLocation = registryAccess.registryOrThrow(Registry.BLOCK_REGISTRY).getKey(this.blockState.getBlock());
|
||||||
#else
|
#else
|
||||||
resourceLocation = registryAccess.registryOrThrow(Registries.BLOCK).getKey(this.blockState.getBlock());
|
resourceLocation = registryAccess.registryOrThrow(Registries.BLOCK).getKey(this.blockState.getBlock());
|
||||||
@@ -325,13 +459,26 @@ public class BlockStateWrapper implements IBlockStateWrapper
|
|||||||
/** will only work if a level is currently loaded */
|
/** will only work if a level is currently loaded */
|
||||||
public static IBlockStateWrapper deserialize(String resourceStateString, ILevelWrapper levelWrapper) throws IOException
|
public static IBlockStateWrapper deserialize(String resourceStateString, ILevelWrapper levelWrapper) throws IOException
|
||||||
{
|
{
|
||||||
if (resourceStateString.equals(AIR_STRING) || resourceStateString.equals("")) // the empty string shouldn't normally happen, but just in case
|
// we need the final string for the concurrent hash map later
|
||||||
|
final String finalResourceStateString = resourceStateString;
|
||||||
|
|
||||||
|
if (finalResourceStateString.equals(AIR_STRING) || finalResourceStateString.isEmpty()) // the empty string shouldn't normally happen, but just in case
|
||||||
{
|
{
|
||||||
return AIR;
|
return AIR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// attempt to use the existing wrapper
|
||||||
|
if (WRAPPER_BY_RESOURCE_LOCATION.containsKey(finalResourceStateString))
|
||||||
|
{
|
||||||
|
return WRAPPER_BY_RESOURCE_LOCATION.get(finalResourceStateString);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// if no wrapper is found, default to air
|
||||||
|
BlockStateWrapper foundWrapper = AIR;
|
||||||
|
try
|
||||||
|
{
|
||||||
// try to parse out the BlockState
|
// try to parse out the BlockState
|
||||||
String blockStatePropertiesString = null; // will be null if no properties were included
|
String blockStatePropertiesString = null; // will be null if no properties were included
|
||||||
int stateSeparatorIndex = resourceStateString.indexOf(STATE_STRING_SEPARATOR);
|
int stateSeparatorIndex = resourceStateString.indexOf(STATE_STRING_SEPARATOR);
|
||||||
@@ -343,12 +490,25 @@ public class BlockStateWrapper implements IBlockStateWrapper
|
|||||||
}
|
}
|
||||||
|
|
||||||
// parse the resource location
|
// parse the resource location
|
||||||
int resourceSeparatorIndex = resourceStateString.indexOf(RESOURCE_LOCATION_SEPARATOR);
|
int separatorIndex = resourceStateString.indexOf(RESOURCE_LOCATION_SEPARATOR);
|
||||||
if (resourceSeparatorIndex == -1)
|
if (separatorIndex == -1)
|
||||||
{
|
{
|
||||||
throw new IOException("Unable to parse Resource Location out of string: [" + resourceStateString + "].");
|
throw new IOException("Unable to parse Resource Location out of string: [" + resourceStateString + "].");
|
||||||
}
|
}
|
||||||
ResourceLocation resourceLocation = new ResourceLocation(resourceStateString.substring(0, resourceSeparatorIndex), resourceStateString.substring(resourceSeparatorIndex + 1));
|
|
||||||
|
ResourceLocation resourceLocation;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
#if MC_VER < MC_1_21
|
||||||
|
resourceLocation = new ResourceLocation(resourceStateString.substring(0, separatorIndex), resourceStateString.substring(separatorIndex + 1));
|
||||||
|
#else
|
||||||
|
resourceLocation = ResourceLocation.fromNamespaceAndPath(resourceStateString.substring(0, separatorIndex), resourceStateString.substring(separatorIndex + 1));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
throw new IOException("No Resource Location found for the string: [" + resourceStateString + "] Error: [" + e.getMessage() + "].");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -356,16 +516,16 @@ public class BlockStateWrapper implements IBlockStateWrapper
|
|||||||
try
|
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
|
// use the given level if possible, otherwise try using the currently loaded one
|
||||||
Level level = (levelWrapper != null ? (Level)levelWrapper.getWrappedMcObject() : null);
|
Level level = (levelWrapper != null ? (Level) levelWrapper.getWrappedMcObject() : null);
|
||||||
level = (level == null ? Minecraft.getInstance().level : level);
|
level = (level == null ? Minecraft.getInstance().level : level);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Block block;
|
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);
|
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();
|
net.minecraft.core.RegistryAccess registryAccess = level.registryAccess();
|
||||||
block = registryAccess.registryOrThrow(Registry.BLOCK_REGISTRY).get(resourceLocation);
|
block = registryAccess.registryOrThrow(Registry.BLOCK_REGISTRY).get(resourceLocation);
|
||||||
#else
|
#else
|
||||||
@@ -382,6 +542,7 @@ public class BlockStateWrapper implements IBlockStateWrapper
|
|||||||
BrokenResourceLocations.add(resourceLocation);
|
BrokenResourceLocations.add(resourceLocation);
|
||||||
LOGGER.warn("Unable to find BlockState with the resourceLocation [" + resourceLocation + "] and properties: [" + blockStatePropertiesString + "]. Air will be used instead, some data may be lost.");
|
LOGGER.warn("Unable to find BlockState with the resourceLocation [" + resourceLocation + "] and properties: [" + blockStatePropertiesString + "]. Air will be used instead, some data may be lost.");
|
||||||
}
|
}
|
||||||
|
|
||||||
return AIR;
|
return AIR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -417,11 +578,20 @@ public class BlockStateWrapper implements IBlockStateWrapper
|
|||||||
|
|
||||||
foundState = block.defaultBlockState();
|
foundState = block.defaultBlockState();
|
||||||
}
|
}
|
||||||
return new BlockStateWrapper(foundState, levelWrapper);
|
|
||||||
|
foundWrapper = new BlockStateWrapper(foundState, levelWrapper);
|
||||||
|
return foundWrapper;
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
throw new IOException("Failed to deserialize the string [" + resourceStateString + "] into a BlockStateWrapper: " + e.getMessage(), e);
|
throw new IOException("Failed to deserialize the string [" + finalResourceStateString + "] into a BlockStateWrapper: " + e.getMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
// put if absent in case two threads deserialize at the same time
|
||||||
|
// unfortunately we can't put everything in a computeIfAbsent() since we also throw exceptions
|
||||||
|
WRAPPER_BY_RESOURCE_LOCATION.putIfAbsent(finalResourceStateString, foundWrapper);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -433,7 +603,7 @@ public class BlockStateWrapper implements IBlockStateWrapper
|
|||||||
|
|
||||||
// alphabetically sort the list so they are always in the same order
|
// alphabetically sort the list so they are always in the same order
|
||||||
List<net.minecraft.world.level.block.state.properties.Property<?>> sortedBlockPropteryList = new ArrayList<>(blockPropertyCollection);
|
List<net.minecraft.world.level.block.state.properties.Property<?>> sortedBlockPropteryList = new ArrayList<>(blockPropertyCollection);
|
||||||
sortedBlockPropteryList.sort((a, b) -> a.getName().compareTo(b.getName()));
|
sortedBlockPropteryList.sort(Comparator.comparing(Property::getName));
|
||||||
|
|
||||||
|
|
||||||
StringBuilder stringBuilder = new StringBuilder();
|
StringBuilder stringBuilder = new StringBuilder();
|
||||||
@@ -457,4 +627,111 @@ public class BlockStateWrapper implements IBlockStateWrapper
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//==============//
|
||||||
|
// Iris methods //
|
||||||
|
//==============//
|
||||||
|
|
||||||
|
private EDhApiBlockMaterial calculateEDhApiBlockMaterialId()
|
||||||
|
{
|
||||||
|
if (this.blockState == null)
|
||||||
|
{
|
||||||
|
return EDhApiBlockMaterial.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 EDhApiBlockMaterial.LEAVES;
|
||||||
|
}
|
||||||
|
else if (this.blockState.is(Blocks.LAVA))
|
||||||
|
{
|
||||||
|
return EDhApiBlockMaterial.LAVA;
|
||||||
|
}
|
||||||
|
else if (this.isLiquid() || this.blockState.is(Blocks.WATER))
|
||||||
|
{
|
||||||
|
return EDhApiBlockMaterial.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 EDhApiBlockMaterial.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 EDhApiBlockMaterial.METAL;
|
||||||
|
}
|
||||||
|
else if (serialString.contains("grass_block"))
|
||||||
|
{
|
||||||
|
return EDhApiBlockMaterial.GRASS;
|
||||||
|
}
|
||||||
|
else if (
|
||||||
|
serialString.contains("dirt")
|
||||||
|
|| serialString.contains("gravel")
|
||||||
|
|| serialString.contains("mud")
|
||||||
|
|| serialString.contains("podzol")
|
||||||
|
|| serialString.contains("mycelium")
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return EDhApiBlockMaterial.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 EDhApiBlockMaterial.DEEPSLATE;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
else if (this.serialString.contains("snow"))
|
||||||
|
{
|
||||||
|
return EDhApiBlockMaterial.SNOW;
|
||||||
|
}
|
||||||
|
else if (serialString.contains("sand"))
|
||||||
|
{
|
||||||
|
return EDhApiBlockMaterial.SAND;
|
||||||
|
}
|
||||||
|
else if (serialString.contains("terracotta"))
|
||||||
|
{
|
||||||
|
return EDhApiBlockMaterial.TERRACOTTA;
|
||||||
|
}
|
||||||
|
else if (this.blockState.is(BlockTags.BASE_STONE_NETHER))
|
||||||
|
{
|
||||||
|
return EDhApiBlockMaterial.NETHER_STONE;
|
||||||
|
}
|
||||||
|
else if (serialString.contains("stone")
|
||||||
|
|| serialString.contains("ore"))
|
||||||
|
{
|
||||||
|
return EDhApiBlockMaterial.STONE;
|
||||||
|
}
|
||||||
|
else if (this.blockState.getLightEmission() > 0)
|
||||||
|
{
|
||||||
|
return EDhApiBlockMaterial.ILLUMINATED;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return EDhApiBlockMaterial.UNKNOWN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -40,11 +40,11 @@ public class TextureAtlasSpriteWrapper
|
|||||||
*/
|
*/
|
||||||
public static int getPixelRGBA(TextureAtlasSprite sprite, int frameIndex, int x, int y)
|
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(
|
return sprite.mainImage[0].getPixelRGBA(
|
||||||
x + sprite.framesX[frameIndex] * sprite.getWidth(),
|
x + sprite.framesX[frameIndex] * sprite.getWidth(),
|
||||||
y + sprite.framesY[frameIndex] * sprite.getHeight());
|
y + sprite.framesY[frameIndex] * sprite.getHeight());
|
||||||
#elif PRE_MC_1_19_4
|
#elif MC_VER < MC_1_19_4
|
||||||
if (sprite.animatedTexture != null)
|
if (sprite.animatedTexture != null)
|
||||||
{
|
{
|
||||||
x += sprite.animatedTexture.getFrameX(frameIndex) * sprite.width;
|
x += sprite.animatedTexture.getFrameX(frameIndex) * sprite.width;
|
||||||
|
|||||||
+3
-15
@@ -19,7 +19,6 @@
|
|||||||
|
|
||||||
package com.seibel.distanthorizons.common.wrappers.block;
|
package com.seibel.distanthorizons.common.wrappers.block;
|
||||||
|
|
||||||
import com.seibel.distanthorizons.common.LodCommonMain;
|
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.core.Direction;
|
import net.minecraft.core.Direction;
|
||||||
import net.minecraft.world.level.*;
|
import net.minecraft.world.level.*;
|
||||||
@@ -50,7 +49,7 @@ public class TintGetterOverrideFast implements BlockAndTintGetter
|
|||||||
|
|
||||||
private Biome _getBiome(BlockPos pos)
|
private Biome _getBiome(BlockPos pos)
|
||||||
{
|
{
|
||||||
#if POST_MC_1_18_2
|
#if MC_VER >= MC_1_18_2
|
||||||
return parent.getBiome(pos).value();
|
return parent.getBiome(pos).value();
|
||||||
#else
|
#else
|
||||||
return parent.getBiome(pos);
|
return parent.getBiome(pos);
|
||||||
@@ -58,18 +57,7 @@ public class TintGetterOverrideFast implements BlockAndTintGetter
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getBlockTint(BlockPos blockPos, ColorResolver colorResolver)
|
public int getBlockTint(BlockPos blockPos, ColorResolver colorResolver) { return colorResolver.getColor(this._getBiome(blockPos), blockPos.getX(), blockPos.getZ()); }
|
||||||
{
|
|
||||||
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());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public float getShade(Direction direction, boolean bl) { return this.parent.getShade(direction, bl); }
|
public float getShade(Direction direction, boolean bl) { return this.parent.getShade(direction, bl); }
|
||||||
@@ -167,7 +155,7 @@ public class TintGetterOverrideFast implements BlockAndTintGetter
|
|||||||
return parent.getMaxBuildHeight();
|
return parent.getMaxBuildHeight();
|
||||||
}
|
}
|
||||||
|
|
||||||
#if POST_MC_1_17_1
|
#if MC_VER >= MC_1_17_1
|
||||||
@Override
|
@Override
|
||||||
public <T extends BlockEntity> Optional<T> getBlockEntity(BlockPos blockPos, BlockEntityType<T> blockEntityType)
|
public <T extends BlockEntity> Optional<T> getBlockEntity(BlockPos blockPos, BlockEntityType<T> blockEntityType)
|
||||||
{
|
{
|
||||||
|
|||||||
+31
-122
@@ -19,7 +19,6 @@
|
|||||||
|
|
||||||
package com.seibel.distanthorizons.common.wrappers.block;
|
package com.seibel.distanthorizons.common.wrappers.block;
|
||||||
|
|
||||||
import com.seibel.distanthorizons.common.LodCommonMain;
|
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.core.Cursor3D;
|
import net.minecraft.core.Cursor3D;
|
||||||
import net.minecraft.core.Direction;
|
import net.minecraft.core.Direction;
|
||||||
@@ -53,7 +52,7 @@ public class TintGetterOverrideSmooth implements BlockAndTintGetter
|
|||||||
|
|
||||||
private Biome _getBiome(BlockPos pos)
|
private Biome _getBiome(BlockPos pos)
|
||||||
{
|
{
|
||||||
#if POST_MC_1_18_2
|
#if MC_VER >= MC_1_18_2
|
||||||
return parent.getBiome(pos).value();
|
return parent.getBiome(pos).value();
|
||||||
#else
|
#else
|
||||||
return parent.getBiome(pos);
|
return parent.getBiome(pos);
|
||||||
@@ -74,16 +73,7 @@ public class TintGetterOverrideSmooth implements BlockAndTintGetter
|
|||||||
while (cursor3D.advance())
|
while (cursor3D.advance())
|
||||||
{
|
{
|
||||||
mutableBlockPos.set(cursor3D.nextX(), cursor3D.nextY(), cursor3D.nextZ());
|
mutableBlockPos.set(cursor3D.nextX(), cursor3D.nextY(), cursor3D.nextZ());
|
||||||
int n;
|
int n = colorResolver.getColor(this._getBiome(mutableBlockPos), mutableBlockPos.getX(), mutableBlockPos.getZ());
|
||||||
if (LodCommonMain.forgeMethodCaller != null)
|
|
||||||
{
|
|
||||||
n = LodCommonMain.forgeMethodCaller.colorResolverGetColor(colorResolver, _getBiome(mutableBlockPos),
|
|
||||||
mutableBlockPos.getX(), mutableBlockPos.getZ());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
n = colorResolver.getColor(_getBiome(mutableBlockPos), mutableBlockPos.getX(), mutableBlockPos.getZ());
|
|
||||||
}
|
|
||||||
|
|
||||||
k += (n & 0xFF0000) >> 16;
|
k += (n & 0xFF0000) >> 16;
|
||||||
l += (n & 0xFF00) >> 8;
|
l += (n & 0xFF00) >> 8;
|
||||||
@@ -93,177 +83,96 @@ public class TintGetterOverrideSmooth implements BlockAndTintGetter
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getBlockTint(BlockPos blockPos, ColorResolver colorResolver)
|
public int getBlockTint(BlockPos blockPos, ColorResolver colorResolver) { return this.calculateBlockTint(blockPos, colorResolver); }
|
||||||
{
|
|
||||||
return calculateBlockTint(blockPos, colorResolver);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public float getShade(Direction direction, boolean bl) { return this.parent.getShade(direction, bl); }
|
public float getShade(Direction direction, boolean bl) { return this.parent.getShade(direction, bl); }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public LevelLightEngine getLightEngine()
|
public LevelLightEngine getLightEngine() { return this.parent.getLightEngine(); }
|
||||||
{
|
|
||||||
return parent.getLightEngine();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getBrightness(LightLayer lightLayer, BlockPos blockPos)
|
public int getBrightness(LightLayer lightLayer, BlockPos blockPos) { return this.parent.getBrightness(lightLayer, blockPos); }
|
||||||
{
|
|
||||||
return parent.getBrightness(lightLayer, blockPos);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getRawBrightness(BlockPos blockPos, int i)
|
public int getRawBrightness(BlockPos blockPos, int i) { return this.parent.getRawBrightness(blockPos, i); }
|
||||||
{
|
|
||||||
return parent.getRawBrightness(blockPos, i);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean canSeeSky(BlockPos blockPos)
|
public boolean canSeeSky(BlockPos blockPos) { return this.parent.canSeeSky(blockPos); }
|
||||||
{
|
|
||||||
return parent.canSeeSky(blockPos);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Nullable
|
@Nullable
|
||||||
public BlockEntity getBlockEntity(BlockPos blockPos)
|
public BlockEntity getBlockEntity(BlockPos blockPos) { return this.parent.getBlockEntity(blockPos); }
|
||||||
{
|
|
||||||
return parent.getBlockEntity(blockPos);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BlockState getBlockState(BlockPos blockPos)
|
public BlockState getBlockState(BlockPos blockPos) { return this.parent.getBlockState(blockPos); }
|
||||||
{
|
|
||||||
return parent.getBlockState(blockPos);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FluidState getFluidState(BlockPos blockPos)
|
public FluidState getFluidState(BlockPos blockPos) { return this.parent.getFluidState(blockPos); }
|
||||||
{
|
|
||||||
return parent.getFluidState(blockPos);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getLightEmission(BlockPos blockPos)
|
public int getLightEmission(BlockPos blockPos) { return this.parent.getLightEmission(blockPos); }
|
||||||
{
|
|
||||||
return parent.getLightEmission(blockPos);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getMaxLightLevel()
|
public int getMaxLightLevel() { return this.parent.getMaxLightLevel(); }
|
||||||
{
|
|
||||||
return parent.getMaxLightLevel();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Stream<BlockState> getBlockStates(AABB aABB)
|
public Stream<BlockState> getBlockStates(AABB aABB) { return this.parent.getBlockStates(aABB); }
|
||||||
{
|
|
||||||
return parent.getBlockStates(aABB);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BlockHitResult clip(ClipContext clipContext)
|
public BlockHitResult clip(ClipContext clipContext) { return this.parent.clip(clipContext); }
|
||||||
{
|
|
||||||
return parent.clip(clipContext);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Nullable
|
@Nullable
|
||||||
public BlockHitResult clipWithInteractionOverride(Vec3 vec3, Vec3 vec32, BlockPos blockPos, VoxelShape voxelShape, BlockState blockState)
|
public BlockHitResult clipWithInteractionOverride(Vec3 vec3, Vec3 vec32, BlockPos blockPos, VoxelShape voxelShape, BlockState blockState)
|
||||||
{
|
{
|
||||||
return parent.clipWithInteractionOverride(vec3, vec32, blockPos, voxelShape, blockState);
|
return this.parent.clipWithInteractionOverride(vec3, vec32, blockPos, voxelShape, blockState);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double getBlockFloorHeight(VoxelShape voxelShape, Supplier<VoxelShape> supplier)
|
public double getBlockFloorHeight(VoxelShape voxelShape, Supplier<VoxelShape> supplier) { return this.parent.getBlockFloorHeight(voxelShape, supplier); }
|
||||||
{
|
|
||||||
return parent.getBlockFloorHeight(voxelShape, supplier);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double getBlockFloorHeight(BlockPos blockPos)
|
public double getBlockFloorHeight(BlockPos blockPos) { return this.parent.getBlockFloorHeight(blockPos); }
|
||||||
{
|
|
||||||
return parent.getBlockFloorHeight(blockPos);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getMaxBuildHeight()
|
public int getMaxBuildHeight() { return this.parent.getMaxBuildHeight(); }
|
||||||
{
|
|
||||||
return parent.getMaxBuildHeight();
|
|
||||||
}
|
|
||||||
|
|
||||||
#if POST_MC_1_17_1
|
#if MC_VER >= MC_1_17_1
|
||||||
@Override
|
@Override
|
||||||
public <T extends BlockEntity> Optional<T> getBlockEntity(BlockPos blockPos, BlockEntityType<T> blockEntityType)
|
public <T extends BlockEntity> Optional<T> getBlockEntity(BlockPos blockPos, BlockEntityType<T> blockEntityType) { return this.parent.getBlockEntity(blockPos, blockEntityType); }
|
||||||
{
|
|
||||||
return parent.getBlockEntity(blockPos, blockEntityType);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BlockHitResult isBlockInLine(ClipBlockStateContext clipBlockStateContext)
|
public BlockHitResult isBlockInLine(ClipBlockStateContext clipBlockStateContext) { return this.parent.isBlockInLine(clipBlockStateContext); }
|
||||||
{
|
|
||||||
return parent.isBlockInLine(clipBlockStateContext);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getHeight()
|
public int getHeight() { return this.parent.getHeight(); }
|
||||||
{
|
|
||||||
return parent.getHeight();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getMinBuildHeight()
|
public int getMinBuildHeight() { return this.parent.getMinBuildHeight(); }
|
||||||
{
|
|
||||||
return parent.getMinBuildHeight();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getSectionsCount()
|
public int getSectionsCount() { return this.parent.getSectionsCount(); }
|
||||||
{
|
|
||||||
return parent.getSectionsCount();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getMinSection()
|
public int getMinSection() { return this.parent.getMinSection(); }
|
||||||
{
|
|
||||||
return parent.getMinSection();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getMaxSection()
|
public int getMaxSection() { return this.parent.getMaxSection(); }
|
||||||
{
|
|
||||||
return parent.getMaxSection();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isOutsideBuildHeight(BlockPos blockPos)
|
public boolean isOutsideBuildHeight(BlockPos blockPos) { return this.parent.isOutsideBuildHeight(blockPos); }
|
||||||
{
|
|
||||||
return parent.isOutsideBuildHeight(blockPos);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isOutsideBuildHeight(int i)
|
public boolean isOutsideBuildHeight(int i) { return this.parent.isOutsideBuildHeight(i); }
|
||||||
{
|
|
||||||
return parent.isOutsideBuildHeight(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getSectionIndex(int i)
|
public int getSectionIndex(int i) { return this.parent.getSectionIndex(i); }
|
||||||
{
|
|
||||||
return parent.getSectionIndex(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getSectionIndexFromSectionY(int i)
|
public int getSectionIndexFromSectionY(int i) { return this.parent.getSectionIndexFromSectionY(i); }
|
||||||
{
|
|
||||||
return parent.getSectionIndexFromSectionY(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getSectionYFromSectionIndex(int i)
|
public int getSectionYFromSectionIndex(int i) { return this.parent.getSectionYFromSectionIndex(i); }
|
||||||
{
|
|
||||||
return parent.getSectionYFromSectionIndex(i);
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|||||||
+62
-14
@@ -19,72 +19,120 @@
|
|||||||
|
|
||||||
package com.seibel.distanthorizons.common.wrappers.block;
|
package com.seibel.distanthorizons.common.wrappers.block;
|
||||||
|
|
||||||
|
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||||
|
import com.seibel.distanthorizons.core.util.ColorUtil;
|
||||||
|
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.core.Direction;
|
import net.minecraft.core.Direction;
|
||||||
import net.minecraft.world.level.*;
|
import net.minecraft.world.level.*;
|
||||||
import net.minecraft.world.level.biome.Biome;
|
import net.minecraft.world.level.biome.Biome;
|
||||||
|
import net.minecraft.world.level.biome.Biomes;
|
||||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
import net.minecraft.world.level.lighting.LevelLightEngine;
|
import net.minecraft.world.level.lighting.LevelLightEngine;
|
||||||
import net.minecraft.world.level.material.FluidState;
|
import net.minecraft.world.level.material.FluidState;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
#if POST_MC_1_18_2
|
#if MC_VER >= MC_1_18_2
|
||||||
import net.minecraft.core.Holder;
|
import net.minecraft.core.Holder;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
public class TintWithoutLevelOverrider implements BlockAndTintGetter
|
public class TintWithoutLevelOverrider implements BlockAndTintGetter
|
||||||
{
|
{
|
||||||
final BiomeWrapper biome;
|
/**
|
||||||
|
* This will only ever be null if there was an issue with {@link IClientLevelWrapper#getPlainsBiomeWrapper()}
|
||||||
|
* but {@link Nullable} is there just in case.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
private final Biome biome;
|
||||||
|
|
||||||
public TintWithoutLevelOverrider(BiomeWrapper biome)
|
|
||||||
|
|
||||||
|
public TintWithoutLevelOverrider(BiomeWrapper biomeWrapper, IClientLevelWrapper clientLevelWrapper)
|
||||||
{
|
{
|
||||||
this.biome = biome;
|
// try to get the wrapped biome
|
||||||
|
Biome unwrappedBiome = null;
|
||||||
|
if (biomeWrapper.biome != null)
|
||||||
|
{
|
||||||
|
unwrappedBiome = unwrap(biomeWrapper.biome);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(unwrappedBiome == null)
|
||||||
|
{
|
||||||
|
// we are looking at the empty biome wrapper, try using plains as a backup
|
||||||
|
BiomeWrapper plainsBiomeWrapper = ((BiomeWrapper) clientLevelWrapper.getPlainsBiomeWrapper());
|
||||||
|
if (plainsBiomeWrapper != null)
|
||||||
|
{
|
||||||
|
unwrappedBiome = unwrap(plainsBiomeWrapper.biome);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.biome = unwrappedBiome;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getBlockTint(BlockPos blockPos, ColorResolver colorResolver)
|
public int getBlockTint(@NotNull BlockPos blockPos, @NotNull ColorResolver colorResolver)
|
||||||
{
|
{
|
||||||
return colorResolver.getColor(_unwrap(biome.biome), blockPos.getX(), blockPos.getZ());
|
if (this.biome != null)
|
||||||
|
{
|
||||||
|
return colorResolver.getColor(this.biome, blockPos.getX(), blockPos.getZ());
|
||||||
}
|
}
|
||||||
private Biome _unwrap(#if POST_MC_1_18_2 Holder<Biome> #else Biome #endif biome)
|
else
|
||||||
{
|
{
|
||||||
#if POST_MC_1_18_2
|
// hopefully unneeded debug color
|
||||||
|
return ColorUtil.CYAN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Biome unwrap(#if MC_VER >= MC_1_18_2 Holder<Biome> #else Biome #endif biome)
|
||||||
|
{
|
||||||
|
#if MC_VER >= MC_1_18_2
|
||||||
return biome.value();
|
return biome.value();
|
||||||
#else
|
#else
|
||||||
return biome;
|
return biome;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//================//
|
||||||
|
// unused methods //
|
||||||
|
//================//
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public float getShade(Direction direction, boolean shade)
|
public float getShade(@NotNull Direction direction, boolean shade)
|
||||||
{
|
{
|
||||||
throw new UnsupportedOperationException("ERROR: getShade() called on TintWithoutLevelOverrider. Object is for tinting only.");
|
throw new UnsupportedOperationException("ERROR: getShade() called on TintWithoutLevelOverrider. Object is for tinting only.");
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public LevelLightEngine getLightEngine()
|
public @NotNull LevelLightEngine getLightEngine()
|
||||||
{
|
{
|
||||||
throw new UnsupportedOperationException("ERROR: getLightEngine() called on TintWithoutLevelOverrider. Object is for tinting only.");
|
throw new UnsupportedOperationException("ERROR: getLightEngine() called on TintWithoutLevelOverrider. Object is for tinting only.");
|
||||||
}
|
}
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public BlockEntity getBlockEntity(BlockPos pos)
|
public BlockEntity getBlockEntity(@NotNull BlockPos pos)
|
||||||
{
|
{
|
||||||
throw new UnsupportedOperationException("ERROR: getBlockEntity() called on TintWithoutLevelOverrider. Object is for tinting only.");
|
throw new UnsupportedOperationException("ERROR: getBlockEntity() called on TintWithoutLevelOverrider. Object is for tinting only.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BlockState getBlockState(BlockPos pos)
|
public @NotNull BlockState getBlockState(@NotNull BlockPos pos)
|
||||||
{
|
{
|
||||||
throw new UnsupportedOperationException("ERROR: getBlockState() called on TintWithoutLevelOverrider. Object is for tinting only.");
|
throw new UnsupportedOperationException("ERROR: getBlockState() called on TintWithoutLevelOverrider. Object is for tinting only.");
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public FluidState getFluidState(BlockPos pos)
|
public @NotNull FluidState getFluidState(@NotNull BlockPos pos)
|
||||||
{
|
{
|
||||||
throw new UnsupportedOperationException("ERROR: getFluidState() called on TintWithoutLevelOverrider. Object is for tinting only.");
|
throw new UnsupportedOperationException("ERROR: getFluidState() called on TintWithoutLevelOverrider. Object is for tinting only.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if MC_1_17_1 || POST_MC_1_18_2
|
#if MC_VER >= MC_1_17_1
|
||||||
@Override
|
@Override
|
||||||
public int getHeight()
|
public int getHeight()
|
||||||
{
|
{
|
||||||
|
|||||||
+4
-4
@@ -30,7 +30,7 @@ import net.minecraft.world.level.lighting.LevelLightEngine;
|
|||||||
import net.minecraft.world.level.material.FluidState;
|
import net.minecraft.world.level.material.FluidState;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
#if POST_MC_1_18_2
|
#if MC_VER >= MC_1_18_2
|
||||||
import net.minecraft.core.Holder;
|
import net.minecraft.core.Holder;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -49,9 +49,9 @@ public class TintWithoutLevelSmoothOverrider implements BlockAndTintGetter
|
|||||||
{
|
{
|
||||||
return colorResolver.getColor(_unwrap(biome.biome), blockPos.getX(), blockPos.getZ());
|
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();
|
return biome.value();
|
||||||
#else
|
#else
|
||||||
return biome;
|
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
|
@Override
|
||||||
public int getHeight()
|
public int getHeight()
|
||||||
{
|
{
|
||||||
|
|||||||
+1
-1
@@ -29,7 +29,7 @@ import java.util.concurrent.ConcurrentHashMap;
|
|||||||
public class ClientBlockDetailMap
|
public class ClientBlockDetailMap
|
||||||
{
|
{
|
||||||
private final ConcurrentHashMap<BlockState, ClientBlockStateCache> blockCache = new ConcurrentHashMap<>();
|
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;
|
private final ClientLevelWrapper level;
|
||||||
public ClientBlockDetailMap(ClientLevelWrapper level) { this.level = level; }
|
public ClientBlockDetailMap(ClientLevelWrapper level) { this.level = level; }
|
||||||
|
|
||||||
|
|||||||
+144
-39
@@ -38,7 +38,7 @@ import net.minecraft.world.level.block.Block;
|
|||||||
import net.minecraft.world.level.block.FlowerBlock;
|
import net.minecraft.world.level.block.FlowerBlock;
|
||||||
import net.minecraft.world.level.block.LeavesBlock;
|
import net.minecraft.world.level.block.LeavesBlock;
|
||||||
import net.minecraft.world.level.block.RotatedPillarBlock;
|
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;
|
import net.minecraft.util.RandomSource;
|
||||||
#else
|
#else
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
@@ -54,27 +54,31 @@ import java.util.List;
|
|||||||
*/
|
*/
|
||||||
public class ClientBlockStateCache
|
public class ClientBlockStateCache
|
||||||
{
|
{
|
||||||
|
|
||||||
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
|
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
|
||||||
|
|
||||||
private static final HashSet<BlockState> BLOCK_STATES_THAT_NEED_LEVEL = new HashSet<>();
|
private static final HashSet<BlockState> BLOCK_STATES_THAT_NEED_LEVEL = new HashSet<>();
|
||||||
private static final HashSet<BlockState> BROKEN_BLOCK_STATES = new HashSet<>();
|
private static final HashSet<BlockState> BROKEN_BLOCK_STATES = new HashSet<>();
|
||||||
|
|
||||||
#if PRE_MC_1_19_2
|
#if MC_VER < MC_1_19_2
|
||||||
public static final Random random = new Random(0);
|
public static final Random random = new Random(0);
|
||||||
#else
|
#else
|
||||||
public static final RandomSource random = RandomSource.create();
|
public static final RandomSource random = RandomSource.create();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
public final IClientLevelWrapper levelWrapper;
|
||||||
public final BlockState blockState;
|
public final BlockState blockState;
|
||||||
public final LevelReader level;
|
public final LevelReader level;
|
||||||
public final BlockPos pos;
|
public final BlockPos pos;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public ClientBlockStateCache(BlockState blockState, IClientLevelWrapper samplingLevel, DhBlockPos samplingPos)
|
public ClientBlockStateCache(BlockState blockState, IClientLevelWrapper samplingLevel, DhBlockPos samplingPos)
|
||||||
{
|
{
|
||||||
this.blockState = blockState;
|
this.blockState = blockState;
|
||||||
level = (LevelReader) samplingLevel.getWrappedMcObject();
|
this.levelWrapper = samplingLevel;
|
||||||
pos = McObjectConverter.Convert(samplingPos);
|
this.level = (LevelReader) samplingLevel.getWrappedMcObject();
|
||||||
resolveColors();
|
this.pos = McObjectConverter.Convert(samplingPos);
|
||||||
|
this.resolveColors();
|
||||||
//LOGGER.info("ClientBlocKCache created for {}", blockState);
|
//LOGGER.info("ClientBlocKCache created for {}", blockState);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -91,18 +95,98 @@ public class ClientBlockStateCache
|
|||||||
{
|
{
|
||||||
Default,
|
Default,
|
||||||
Flower,
|
Flower,
|
||||||
Leaves;
|
Leaves,
|
||||||
|
Chisel,
|
||||||
|
Glass;
|
||||||
static ColorMode getColorMode(Block b)
|
static ColorMode getColorMode(Block b)
|
||||||
{
|
{
|
||||||
if (b instanceof LeavesBlock) return Leaves;
|
if (b instanceof LeavesBlock) return Leaves;
|
||||||
if (b instanceof FlowerBlock) return Flower;
|
if (b instanceof FlowerBlock) return Flower;
|
||||||
|
if (b.toString().contains("glass")) return Glass;
|
||||||
|
if (b.toString().equals("Block{chiselsandbits:chiseled}")) return Chisel;
|
||||||
return Default;
|
return Default;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Way to efficiently do this was suggested by IMS from sodium. This is where those numbers and support code was lifted from.
|
||||||
|
private static final int MIN_BITS = 0x39000000; // 2^(-13)
|
||||||
|
private static final int MAX_BITS = 0x3f7fffff; // 1.0 - f32::EPSILON
|
||||||
|
private static final float MIN_BOUND = Float.intBitsToFloat(MIN_BITS);
|
||||||
|
private static final float MAX_BOUND = Float.intBitsToFloat(MAX_BITS);
|
||||||
|
|
||||||
|
private static final int[] linearToSrgbTable = new int[] {
|
||||||
|
0x0073000d, 0x007a000d, 0x0080000d, 0x0087000d, 0x008d000d, 0x0094000d, 0x009a000d, 0x00a1000d,
|
||||||
|
0x00a7001a, 0x00b4001a, 0x00c1001a, 0x00ce001a, 0x00da001a, 0x00e7001a, 0x00f4001a, 0x0101001a,
|
||||||
|
0x010e0033, 0x01280033, 0x01410033, 0x015b0033, 0x01750033, 0x018f0033, 0x01a80033, 0x01c20033,
|
||||||
|
0x01dc0067, 0x020f0067, 0x02430067, 0x02760067, 0x02aa0067, 0x02dd0067, 0x03110067, 0x03440067,
|
||||||
|
0x037800ce, 0x03df00ce, 0x044600ce, 0x04ad00ce, 0x051400ce, 0x057b00c5, 0x05dd00bc, 0x063b00b5,
|
||||||
|
0x06970158, 0x07420142, 0x07e30130, 0x087b0120, 0x090b0112, 0x09940106, 0x0a1700fc, 0x0a9500f2,
|
||||||
|
0x0b0f01cb, 0x0bf401ae, 0x0ccb0195, 0x0d950180, 0x0e56016e, 0x0f0d015e, 0x0fbc0150, 0x10630143,
|
||||||
|
0x11070264, 0x1238023e, 0x1357021d, 0x14660201, 0x156601e9, 0x165a01d3, 0x174401c0, 0x182401af,
|
||||||
|
0x18fe0331, 0x1a9602fe, 0x1c1502d2, 0x1d7e02ad, 0x1ed4028d, 0x201a0270, 0x21520256, 0x227d0240,
|
||||||
|
0x239f0443, 0x25c003fe, 0x27bf03c4, 0x29a10392, 0x2b6a0367, 0x2d1d0341, 0x2ebe031f, 0x304d0300,
|
||||||
|
0x31d105b0, 0x34a80555, 0x37520507, 0x39d504c5, 0x3c37048b, 0x3e7c0458, 0x40a8042a, 0x42bd0401,
|
||||||
|
0x44c20798, 0x488e071e, 0x4c1c06b6, 0x4f76065d, 0x52a50610, 0x55ac05cc, 0x5892058f, 0x5b590559,
|
||||||
|
0x5e0c0a23, 0x631c0980, 0x67db08f6, 0x6c55087f, 0x70940818, 0x74a007bd, 0x787d076c, 0x7c330723,
|
||||||
|
};
|
||||||
|
|
||||||
|
private static final float[] srgbToLinearTable = new float[] {
|
||||||
|
0.0f, 0.000303527f, 0.000607054f, 0.00091058103f, 0.001214108f, 0.001517635f, 0.0018211621f, 0.002124689f,
|
||||||
|
0.002428216f, 0.002731743f, 0.00303527f, 0.0033465356f, 0.003676507f, 0.004024717f, 0.004391442f,
|
||||||
|
0.0047769533f, 0.005181517f, 0.0056053917f, 0.0060488326f, 0.006512091f, 0.00699541f, 0.0074990317f,
|
||||||
|
0.008023192f, 0.008568125f, 0.009134057f, 0.009721218f, 0.010329823f, 0.010960094f, 0.011612245f,
|
||||||
|
0.012286487f, 0.012983031f, 0.013702081f, 0.014443844f, 0.015208514f, 0.015996292f, 0.016807375f,
|
||||||
|
0.017641952f, 0.018500218f, 0.019382361f, 0.020288562f, 0.02121901f, 0.022173883f, 0.023153365f,
|
||||||
|
0.02415763f, 0.025186857f, 0.026241222f, 0.027320892f, 0.028426038f, 0.029556843f, 0.03071345f, 0.03189604f,
|
||||||
|
0.033104774f, 0.03433981f, 0.035601325f, 0.036889452f, 0.038204376f, 0.039546248f, 0.04091521f, 0.042311423f,
|
||||||
|
0.043735042f, 0.045186214f, 0.046665095f, 0.048171833f, 0.049706575f, 0.051269468f, 0.052860655f, 0.05448028f,
|
||||||
|
0.056128494f, 0.057805434f, 0.05951124f, 0.06124607f, 0.06301003f, 0.06480328f, 0.06662595f, 0.06847818f,
|
||||||
|
0.07036011f, 0.07227186f, 0.07421358f, 0.07618539f, 0.07818743f, 0.08021983f, 0.082282715f, 0.084376216f,
|
||||||
|
0.086500466f, 0.088655606f, 0.09084173f, 0.09305898f, 0.095307484f, 0.09758736f, 0.09989874f, 0.10224175f,
|
||||||
|
0.10461649f, 0.10702311f, 0.10946172f, 0.111932434f, 0.11443538f, 0.116970696f, 0.11953845f, 0.12213881f,
|
||||||
|
0.12477186f, 0.12743773f, 0.13013652f, 0.13286836f, 0.13563336f, 0.13843165f, 0.14126332f, 0.1441285f,
|
||||||
|
0.1470273f, 0.14995982f, 0.15292618f, 0.1559265f, 0.15896086f, 0.16202943f, 0.16513224f, 0.16826946f,
|
||||||
|
0.17144115f, 0.17464745f, 0.17788847f, 0.1811643f, 0.18447503f, 0.1878208f, 0.19120172f, 0.19461787f,
|
||||||
|
0.19806935f, 0.2015563f, 0.20507877f, 0.2086369f, 0.21223079f, 0.21586053f, 0.21952623f, 0.22322798f,
|
||||||
|
0.22696589f, 0.23074007f, 0.23455065f, 0.23839766f, 0.2422812f, 0.2462014f, 0.25015837f, 0.25415218f,
|
||||||
|
0.2581829f, 0.26225072f, 0.26635566f, 0.27049786f, 0.27467737f, 0.27889434f, 0.2831488f, 0.2874409f,
|
||||||
|
0.2917707f, 0.29613832f, 0.30054384f, 0.30498737f, 0.30946895f, 0.31398875f, 0.31854683f, 0.32314324f,
|
||||||
|
0.32777813f, 0.33245158f, 0.33716366f, 0.34191445f, 0.3467041f, 0.3515327f, 0.35640025f, 0.36130688f,
|
||||||
|
0.3662527f, 0.37123778f, 0.37626222f, 0.3813261f, 0.38642952f, 0.39157256f, 0.3967553f, 0.40197787f,
|
||||||
|
0.4072403f, 0.4125427f, 0.41788515f, 0.42326775f, 0.42869055f, 0.4341537f, 0.43965724f, 0.44520125f,
|
||||||
|
0.45078585f, 0.45641106f, 0.46207705f, 0.46778384f, 0.47353154f, 0.47932023f, 0.48514998f, 0.4910209f,
|
||||||
|
0.49693304f, 0.5028866f, 0.50888145f, 0.5149178f, 0.5209957f, 0.52711535f, 0.5332766f, 0.5394797f,
|
||||||
|
0.5457247f, 0.5520116f, 0.5583406f, 0.5647117f, 0.57112503f, 0.57758063f, 0.5840786f, 0.590619f, 0.597202f,
|
||||||
|
0.60382754f, 0.61049575f, 0.61720675f, 0.62396055f, 0.63075733f, 0.637597f, 0.6444799f, 0.6514058f,
|
||||||
|
0.65837497f, 0.66538745f, 0.67244333f, 0.6795426f, 0.68668544f, 0.69387203f, 0.70110214f, 0.70837605f,
|
||||||
|
0.7156938f, 0.72305536f, 0.730461f, 0.7379107f, 0.7454045f, 0.75294244f, 0.76052475f, 0.7681514f, 0.77582246f,
|
||||||
|
0.78353804f, 0.79129815f, 0.79910296f, 0.8069525f, 0.8148468f, 0.822786f, 0.8307701f, 0.83879924f, 0.84687346f,
|
||||||
|
0.8549928f, 0.8631574f, 0.87136734f, 0.8796226f, 0.8879232f, 0.89626956f, 0.90466136f, 0.913099f, 0.92158204f,
|
||||||
|
0.93011117f, 0.9386859f, 0.9473069f, 0.9559735f, 0.9646866f, 0.9734455f, 0.98225087f, 0.9911022f, 1.0f
|
||||||
|
};
|
||||||
|
|
||||||
|
private static int linearToSrgb(float c) {
|
||||||
|
if (!(c > MIN_BOUND)) {
|
||||||
|
c = MIN_BOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (c > MAX_BOUND) {
|
||||||
|
c = MAX_BOUND;
|
||||||
|
}
|
||||||
|
int inputBits = Float.floatToRawIntBits(c);
|
||||||
|
int entry = linearToSrgbTable[((inputBits - MIN_BITS) >> 20)];
|
||||||
|
|
||||||
|
int bias = (entry >>> 16) << 9;
|
||||||
|
int scale = entry & 0xffff;
|
||||||
|
int t = (inputBits >>> 12) & 0xff;
|
||||||
|
|
||||||
|
return (bias + (scale * t)) >>> 16;
|
||||||
|
}
|
||||||
|
//////////////
|
||||||
|
|
||||||
private static int getWidth(TextureAtlasSprite texture)
|
private static int getWidth(TextureAtlasSprite texture)
|
||||||
{
|
{
|
||||||
#if PRE_MC_1_19_4
|
#if MC_VER < MC_1_19_4
|
||||||
return texture.getWidth();
|
return texture.getWidth();
|
||||||
#else
|
#else
|
||||||
return texture.contents().width();
|
return texture.contents().width();
|
||||||
@@ -111,27 +195,30 @@ public class ClientBlockStateCache
|
|||||||
|
|
||||||
private static int getHeight(TextureAtlasSprite texture)
|
private static int getHeight(TextureAtlasSprite texture)
|
||||||
{
|
{
|
||||||
#if PRE_MC_1_19_4
|
#if MC_VER < MC_1_19_4
|
||||||
return texture.getHeight();
|
return texture.getHeight();
|
||||||
#else
|
#else
|
||||||
return texture.contents().height();
|
return texture.contents().height();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//TODO: Perhaps make this not just use the first frame?
|
//TODO: Perhaps make this not just use the first frame?
|
||||||
private static int calculateColorFromTexture(TextureAtlasSprite texture, ColorMode colorMode)
|
private static int calculateColorFromTexture(TextureAtlasSprite texture, ColorMode colorMode)
|
||||||
{
|
{
|
||||||
int count = 0;
|
int count = 0;
|
||||||
double alpha = 0;
|
int alpha = 0;
|
||||||
double red = 0;
|
double red = 0;
|
||||||
double green = 0;
|
double green = 0;
|
||||||
double blue = 0;
|
double blue = 0;
|
||||||
int tempColor;
|
int tempColor;
|
||||||
|
//make Chiseled block not render. Since ColorMode is set per block, you only need to check it once
|
||||||
|
if (colorMode != ColorMode.Chisel)
|
||||||
{
|
{
|
||||||
// textures normally use u and v instead of x and y
|
// textures normally use u and v instead of x and y
|
||||||
for (int u = 0; u < getWidth(texture); u++)
|
|
||||||
{
|
|
||||||
for (int v = 0; v < getHeight(texture); v++)
|
for (int v = 0; v < getHeight(texture); v++)
|
||||||
|
{
|
||||||
|
for (int u = 0; u < getWidth(texture); u++)
|
||||||
{
|
{
|
||||||
//note: Minecraft color format is: 0xAA BB GG RR
|
//note: Minecraft color format is: 0xAA BB GG RR
|
||||||
//________ DH mod color format is: 0xAA RR GG BB
|
//________ DH mod color format is: 0xAA RR GG BB
|
||||||
@@ -139,33 +226,45 @@ public class ClientBlockStateCache
|
|||||||
//_ OpenGL RGBA format Java Order: 0xAA BB GG RR
|
//_ OpenGL RGBA format Java Order: 0xAA BB GG RR
|
||||||
tempColor = TextureAtlasSpriteWrapper.getPixelRGBA(texture, 0, u, v);
|
tempColor = TextureAtlasSpriteWrapper.getPixelRGBA(texture, 0, u, v);
|
||||||
|
|
||||||
double r = ((tempColor & 0x000000FF)) / 255.;
|
int r = (tempColor & 0x000000FF);
|
||||||
double g = ((tempColor & 0x0000FF00) >>> 8) / 255.;
|
int g = (tempColor & 0x0000FF00) >>> 8;
|
||||||
double b = ((tempColor & 0x00FF0000) >>> 16) / 255.;
|
int b = (tempColor & 0x00FF0000) >>> 16;
|
||||||
double a = ((tempColor & 0xFF000000) >>> 24) / 255.;
|
int a = (tempColor & 0xFF000000) >>> 24;
|
||||||
int scale = 1;
|
int scale = 1;
|
||||||
|
|
||||||
if (colorMode == ColorMode.Leaves)
|
if (colorMode == ColorMode.Leaves)
|
||||||
{
|
{
|
||||||
r *= a;
|
//switch (//FIXME add config option)
|
||||||
g *= a;
|
// case BLACK:
|
||||||
b *= a;
|
// a = 255; //simulate black background of fast leaves
|
||||||
a = 1.;
|
// break;
|
||||||
|
// case IGNORE:
|
||||||
|
if (a == 0) {
|
||||||
|
continue; //same long grass
|
||||||
}
|
}
|
||||||
else if (a == 0.)
|
else
|
||||||
|
{
|
||||||
|
a = 255; //just in case there are semi transparent pixels
|
||||||
|
}
|
||||||
|
// break;
|
||||||
|
// case TRANSPARENT:
|
||||||
|
// break; //do nothing, let it count towards transparency
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (a == 0 && colorMode != ColorMode.Glass)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (colorMode == ColorMode.Flower && (g + 0.1 < b || g + 0.1 < r))
|
else if (colorMode == ColorMode.Flower && (g + 25 < b || g + 25 < r))
|
||||||
{
|
{
|
||||||
scale = FLOWER_COLOR_SCALE;
|
scale = FLOWER_COLOR_SCALE;
|
||||||
}
|
}
|
||||||
|
|
||||||
count += scale;
|
count += scale;
|
||||||
alpha += a * a * scale;
|
//apparently alpha is linear
|
||||||
red += r * r * scale;
|
alpha += a * scale;
|
||||||
green += g * g * scale;
|
//gamma correction is complicated
|
||||||
blue += b * b * scale;
|
red += srgbToLinearTable[r] * a * scale;
|
||||||
|
green += srgbToLinearTable[g] * a * scale;
|
||||||
|
blue += srgbToLinearTable[b] * a * scale;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -177,10 +276,16 @@ public class ClientBlockStateCache
|
|||||||
{
|
{
|
||||||
// determine the average color
|
// determine the average color
|
||||||
tempColor = ColorUtil.rgbToInt(
|
tempColor = ColorUtil.rgbToInt(
|
||||||
(int) (Math.sqrt(alpha / count) * 255.),
|
alpha / count,
|
||||||
(int) (Math.sqrt(red / count) * 255.),
|
linearToSrgb((float) (red / (double) alpha)),
|
||||||
(int) (Math.sqrt(green / count) * 255.),
|
linearToSrgb((float) (green / (double) alpha)),
|
||||||
(int) (Math.sqrt(blue / count) * 255.));
|
linearToSrgb((float) (blue / (double) alpha)));
|
||||||
|
}
|
||||||
|
//check if not missing texture
|
||||||
|
if (tempColor == ColorUtil.rgbToInt(255, 182, 0, 182))
|
||||||
|
{
|
||||||
|
//make it not render at all
|
||||||
|
tempColor = ColorUtil.rgbToInt(0, 255, 255, 255);
|
||||||
}
|
}
|
||||||
return tempColor;
|
return tempColor;
|
||||||
}
|
}
|
||||||
@@ -195,7 +300,7 @@ public class ClientBlockStateCache
|
|||||||
for (Direction direction : DIRECTION_ORDER)
|
for (Direction direction : DIRECTION_ORDER)
|
||||||
{
|
{
|
||||||
quads = Minecraft.getInstance().getModelManager().getBlockModelShaper().
|
quads = Minecraft.getInstance().getModelManager().getBlockModelShaper().
|
||||||
getBlockModel(blockState).getQuads(blockState, direction, random);
|
getBlockModel(blockState).getQuads(blockState, direction, random); // TODO getQuads sometimes throws a "makeThreadingException", is there anything we can do about that? Note: this isn't a critical issue, it just prints an ugly error and the render data will need to be regenered.
|
||||||
if (quads != null && !quads.isEmpty() &&
|
if (quads != null && !quads.isEmpty() &&
|
||||||
!(blockState.getBlock() instanceof RotatedPillarBlock && direction == Direction.UP))
|
!(blockState.getBlock() instanceof RotatedPillarBlock && direction == Direction.UP))
|
||||||
break;
|
break;
|
||||||
@@ -207,12 +312,12 @@ public class ClientBlockStateCache
|
|||||||
}
|
}
|
||||||
if (quads != null && !quads.isEmpty())
|
if (quads != null && !quads.isEmpty())
|
||||||
{
|
{
|
||||||
needPostTinting = quads.get(0).isTinted();
|
needPostTinting = quads.getFirst().isTinted();
|
||||||
needShade = quads.get(0).isShade();
|
needShade = quads.getFirst().isShade();
|
||||||
tintIndex = quads.get(0).getTintIndex();
|
tintIndex = quads.getFirst().getTintIndex();
|
||||||
baseColor = calculateColorFromTexture(
|
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
|
#else quads.getFirst().getSprite(), #endif
|
||||||
ColorMode.getColorMode(blockState.getBlock()));
|
ColorMode.getColorMode(blockState.getBlock()));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -262,7 +367,7 @@ public class ClientBlockStateCache
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
tintColor = Minecraft.getInstance().getBlockColors()
|
tintColor = Minecraft.getInstance().getBlockColors()
|
||||||
.getColor(this.blockState, new TintWithoutLevelOverrider(biome), McObjectConverter.Convert(pos), this.tintIndex);
|
.getColor(this.blockState, new TintWithoutLevelOverrider(biome, this.levelWrapper), McObjectConverter.Convert(pos), this.tintIndex);
|
||||||
}
|
}
|
||||||
catch (UnsupportedOperationException e)
|
catch (UnsupportedOperationException e)
|
||||||
{
|
{
|
||||||
|
|||||||
+1
-1
@@ -29,7 +29,7 @@ import net.minecraft.world.level.block.state.BlockState;
|
|||||||
public class ServerBlockDetailMap
|
public class ServerBlockDetailMap
|
||||||
{
|
{
|
||||||
private final ConcurrentHashMap<BlockState, ServerBlockStateCache> blockCache = new ConcurrentHashMap<>();
|
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;
|
private final ServerLevelWrapper level;
|
||||||
public ServerBlockDetailMap(ServerLevelWrapper level) { this.level = level; }
|
public ServerBlockDetailMap(ServerLevelWrapper level) { this.level = level; }
|
||||||
|
|
||||||
|
|||||||
-216
@@ -1,216 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of the Distant Horizons mod
|
|
||||||
* licensed under the GNU LGPL v3 License.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2020-2023 James Seibel
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
|
||||||
* the Free Software Foundation, version 3.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.seibel.distanthorizons.common.wrappers.chunk;
|
|
||||||
|
|
||||||
import com.seibel.distanthorizons.coreapi.util.BitShiftUtil;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Compact, efficient storage for light levels.
|
|
||||||
* all blocks only take up 4 bits in total,
|
|
||||||
* and if a 16x16x16 area is detected to have the same light level in all positions,
|
|
||||||
* then we store a single byte for that light level, instead of 2 kilobytes.
|
|
||||||
*
|
|
||||||
* @author Builderb0y
|
|
||||||
*/
|
|
||||||
public class ChunkLightStorage
|
|
||||||
{
|
|
||||||
/** the minimum Y level in the chunk which this storage is storing light levels for (inclusive). */
|
|
||||||
public int minY;
|
|
||||||
/** the maximum Y level in the chunk which this storage is storing light levels for (exclusive). */
|
|
||||||
public int maxY;
|
|
||||||
|
|
||||||
/** the data stored in this storage, split up into 16x16x16 areas. */
|
|
||||||
public LightSection[] lightSections;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public ChunkLightStorage(int minY, int maxY)
|
|
||||||
{
|
|
||||||
this.minY = minY;
|
|
||||||
this.maxY = maxY;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public int get(int x, int y, int z)
|
|
||||||
{
|
|
||||||
if (y < this.minY)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (y >= this.maxY)
|
|
||||||
{
|
|
||||||
return 15;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.lightSections != null)
|
|
||||||
{
|
|
||||||
LightSection lightSection = this.lightSections[BitShiftUtil.divideByPowerOfTwo(y - this.minY, 4)];
|
|
||||||
if (lightSection != null)
|
|
||||||
{
|
|
||||||
return lightSection.get(x, y, z);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void set(int x, int y, int z, int lightLevel)
|
|
||||||
{
|
|
||||||
if (y < this.minY || y >= this.maxY)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//populate array if it doesn't exist.
|
|
||||||
if (this.lightSections == null)
|
|
||||||
{
|
|
||||||
this.lightSections = new LightSection[BitShiftUtil.divideByPowerOfTwo(this.maxY - this.minY, 4)];
|
|
||||||
}
|
|
||||||
|
|
||||||
int index = (y - this.minY) >> 4;
|
|
||||||
LightSection lightSection = this.lightSections[index];
|
|
||||||
|
|
||||||
//populate lightSection in array if it doesn't exist.
|
|
||||||
if (lightSection == null)
|
|
||||||
{
|
|
||||||
lightSection = new LightSection(0);
|
|
||||||
this.lightSections[index] = lightSection;
|
|
||||||
}
|
|
||||||
lightSection.set(x, y, z, lightLevel);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//================//
|
|
||||||
// helper classes //
|
|
||||||
//================//
|
|
||||||
|
|
||||||
public static class LightSection
|
|
||||||
{
|
|
||||||
public byte constantValue;
|
|
||||||
public long[] data;
|
|
||||||
public short[] counts;
|
|
||||||
|
|
||||||
public LightSection(int initialValue)
|
|
||||||
{
|
|
||||||
this.constantValue = (byte) (initialValue);
|
|
||||||
this.counts = new short[16];
|
|
||||||
this.counts[initialValue] = 16 * 16 * 16;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int get(int x, int y, int z)
|
|
||||||
{
|
|
||||||
if (this.constantValue >= 0)
|
|
||||||
{
|
|
||||||
return this.constantValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
x &= 15;
|
|
||||||
y &= 15;
|
|
||||||
z &= 15;
|
|
||||||
long bits = this.data[(z << 4) | x];
|
|
||||||
return ((int) (bits >>> (y << 2))) & 15;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void set(int x, int y, int z, int lightLevel)
|
|
||||||
{
|
|
||||||
int oldLightLevel = -1;
|
|
||||||
if (this.constantValue >= 0)
|
|
||||||
{
|
|
||||||
oldLightLevel = this.constantValue;
|
|
||||||
|
|
||||||
//if the light level didn't change, then there's nothing to do.
|
|
||||||
if (oldLightLevel == lightLevel) return;
|
|
||||||
|
|
||||||
//if we are a constant value and need to change something,
|
|
||||||
//then that means we need to convert to a non-constant value.
|
|
||||||
this.data = DataRecycler.get();
|
|
||||||
|
|
||||||
//repeat oldLightLevel 16 times as a bit pattern.
|
|
||||||
long payload = oldLightLevel;
|
|
||||||
payload |= payload << 4;
|
|
||||||
payload |= payload << 8;
|
|
||||||
payload |= payload << 16;
|
|
||||||
payload |= payload << 32;
|
|
||||||
|
|
||||||
//fill our data with our constant value.
|
|
||||||
Arrays.fill(this.data, payload);
|
|
||||||
|
|
||||||
//we are no longer a constant value.
|
|
||||||
this.constantValue = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
x &= 15;
|
|
||||||
y &= 15;
|
|
||||||
z &= 15;
|
|
||||||
int index = (z << 4) | x;
|
|
||||||
long bits = this.data[index];
|
|
||||||
//if we weren't a constant value before, now's the time to initialize oldLightLevel.
|
|
||||||
if (oldLightLevel < 0)
|
|
||||||
{
|
|
||||||
oldLightLevel = ((int) (bits >>> (y << 2))) & 15;
|
|
||||||
}
|
|
||||||
//clear the 4 bits that correspond to the light level at x, y, z...
|
|
||||||
bits &= ~(15L << (y << 2));
|
|
||||||
//...and then re-populate those bits with the new light level.
|
|
||||||
bits |= ((long) (lightLevel)) << (y << 2);
|
|
||||||
//store the updated bits in our data.
|
|
||||||
this.data[index] = bits;
|
|
||||||
|
|
||||||
//we have one less of the old light level...
|
|
||||||
this.counts[oldLightLevel]--;
|
|
||||||
//...and one more of the new level.
|
|
||||||
//if the number associated with the new level is now 4096 (AKA 16 ^ 3),
|
|
||||||
//then this implies every position in this section has the same light level,
|
|
||||||
//and therefore we can convert back to a constant value.
|
|
||||||
if (++this.counts[lightLevel] == 4096)
|
|
||||||
{
|
|
||||||
this.constantValue = (byte) (lightLevel);
|
|
||||||
DataRecycler.reclaim(this.data);
|
|
||||||
this.data = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
static class DataRecycler
|
|
||||||
{
|
|
||||||
private static final ArrayList<long[]> recycled = new ArrayList<>(256);
|
|
||||||
|
|
||||||
static synchronized long[] get()
|
|
||||||
{
|
|
||||||
if (recycled.isEmpty())
|
|
||||||
{
|
|
||||||
return new long[256];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return recycled.remove(recycled.size() - 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static synchronized void reclaim(long[] data) { if (recycled.size() < 256) recycled.add(data); }
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
+212
-188
@@ -25,20 +25,18 @@ import com.seibel.distanthorizons.common.wrappers.worldGeneration.mimicObject.Dh
|
|||||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||||
import com.seibel.distanthorizons.core.pos.DhBlockPos;
|
import com.seibel.distanthorizons.core.pos.DhBlockPos;
|
||||||
import com.seibel.distanthorizons.core.pos.DhChunkPos;
|
import com.seibel.distanthorizons.core.pos.DhChunkPos;
|
||||||
import com.seibel.distanthorizons.core.util.LodUtil;
|
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.block.IBlockStateWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.block.IBlockStateWrapper;
|
||||||
|
import com.seibel.distanthorizons.core.wrapperInterfaces.chunk.ChunkLightStorage;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.chunk.IChunkWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.chunk.IChunkWrapper;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IBiomeWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IBiomeWrapper;
|
||||||
|
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper;
|
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.ClientChunkCache;
|
||||||
import net.minecraft.client.multiplayer.ClientLevel;
|
import net.minecraft.client.multiplayer.ClientLevel;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.world.level.LevelReader;
|
import net.minecraft.world.level.LevelReader;
|
||||||
import net.minecraft.world.level.LightLayer;
|
import net.minecraft.world.level.LightLayer;
|
||||||
import net.minecraft.world.level.chunk.ChunkAccess;
|
import net.minecraft.world.level.chunk.ChunkAccess;
|
||||||
import net.minecraft.world.level.chunk.ChunkStatus;
|
|
||||||
import net.minecraft.world.level.chunk.LevelChunk;
|
import net.minecraft.world.level.chunk.LevelChunk;
|
||||||
import net.minecraft.world.level.levelgen.Heightmap;
|
import net.minecraft.world.level.levelgen.Heightmap;
|
||||||
|
|
||||||
@@ -47,41 +45,45 @@ import org.apache.logging.log4j.Logger;
|
|||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||||
|
|
||||||
#if POST_MC_1_17_1
|
#if MC_VER >= MC_1_17_1
|
||||||
import net.minecraft.core.QuartPos;
|
import net.minecraft.core.QuartPos;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if MC_1_16_5
|
#if MC_VER == MC_1_16_5
|
||||||
import net.minecraft.world.level.chunk.LevelChunkSection;
|
import net.minecraft.world.level.chunk.LevelChunkSection;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if MC_1_17_1
|
#if MC_VER == MC_1_17_1
|
||||||
import net.minecraft.world.level.chunk.LevelChunkSection;
|
import net.minecraft.world.level.chunk.LevelChunkSection;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if MC_1_18_2
|
#if MC_VER == MC_1_18_2
|
||||||
import net.minecraft.world.level.chunk.LevelChunkSection;
|
import net.minecraft.world.level.chunk.LevelChunkSection;
|
||||||
#endif
|
#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;
|
import net.minecraft.world.level.chunk.LevelChunkSection;
|
||||||
#endif
|
#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.chunk.LevelChunkSection;
|
||||||
import net.minecraft.world.level.lighting.LevelLightEngine;
|
import net.minecraft.world.level.lighting.LevelLightEngine;
|
||||||
import net.minecraft.core.SectionPos;
|
import net.minecraft.core.SectionPos;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if MC_VER <= MC_1_20_4
|
||||||
|
import net.minecraft.world.level.chunk.ChunkStatus;
|
||||||
|
#else
|
||||||
|
import net.minecraft.world.level.chunk.status.ChunkStatus;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
public class ChunkWrapper implements IChunkWrapper
|
public class ChunkWrapper implements IChunkWrapper
|
||||||
{
|
{
|
||||||
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
|
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 = 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. */
|
/** can be used for interactions with the underlying chunk where creating new BlockPos objects could cause issues for the garbage collector. */
|
||||||
private static final ThreadLocal<BlockPos.MutableBlockPos> MUTABLE_BLOCK_POS_REF = ThreadLocal.withInitial(() -> new BlockPos.MutableBlockPos());
|
private static final ThreadLocal<BlockPos.MutableBlockPos> MUTABLE_BLOCK_POS_REF = ThreadLocal.withInitial(BlockPos.MutableBlockPos::new);
|
||||||
|
|
||||||
|
|
||||||
private final ChunkAccess chunk;
|
private final ChunkAccess chunk;
|
||||||
@@ -100,6 +102,11 @@ public class ChunkWrapper implements IChunkWrapper
|
|||||||
|
|
||||||
private boolean useDhLighting;
|
private boolean useDhLighting;
|
||||||
|
|
||||||
|
private int minNonEmptyHeight = Integer.MIN_VALUE;
|
||||||
|
private int maxNonEmptyHeight = Integer.MAX_VALUE;
|
||||||
|
|
||||||
|
private int blockBiomeHashCode = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Due to vanilla `isClientLightReady()` not being designed for use by a non-render thread, it may return 'true'
|
* 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).
|
* before the light engine has ticked, (right after all light changes is marked by the engine to be processed).
|
||||||
@@ -139,34 +146,48 @@ public class ChunkWrapper implements IChunkWrapper
|
|||||||
|
|
||||||
|
|
||||||
//=========//
|
//=========//
|
||||||
// methods //
|
// getters //
|
||||||
//=========//
|
//=========//
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getHeight()
|
public int getHeight() { return getHeight(this.chunk); }
|
||||||
|
public static int getHeight(ChunkAccess chunk)
|
||||||
{
|
{
|
||||||
#if PRE_MC_1_17_1
|
#if MC_VER < MC_1_17_1
|
||||||
return 255;
|
return 255;
|
||||||
#else
|
#else
|
||||||
return this.chunk.getHeight();
|
return chunk.getHeight();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getMinBuildHeight()
|
public int getMinBuildHeight() { return getMinBuildHeight(this.chunk); }
|
||||||
|
public static int getMinBuildHeight(ChunkAccess chunk)
|
||||||
{
|
{
|
||||||
#if PRE_MC_1_17_1
|
#if MC_VER < MC_1_17_1
|
||||||
return 0;
|
return 0;
|
||||||
#else
|
#else
|
||||||
return this.chunk.getMinBuildHeight();
|
return chunk.getMinBuildHeight();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@Override
|
|
||||||
public int getMaxBuildHeight() { return this.chunk.getMaxBuildHeight(); }
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getMinFilledHeight()
|
public int getMaxBuildHeight() { return getMaxBuildHeight(this.chunk); }
|
||||||
|
public static int getMaxBuildHeight(ChunkAccess chunk) { return chunk.getMaxBuildHeight(); }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
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();
|
LevelChunkSection[] sections = this.chunk.getSections();
|
||||||
for (int index = 0; index < sections.length; index++)
|
for (int index = 0; index < sections.length; index++)
|
||||||
{
|
{
|
||||||
@@ -175,28 +196,61 @@ public class ChunkWrapper implements IChunkWrapper
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if MC_1_16_5
|
if (!isChunkSectionEmpty(sections[index]))
|
||||||
if (!sections[index].isEmpty())
|
|
||||||
{
|
{
|
||||||
// convert from an index to a block coordinate
|
this.minNonEmptyHeight = this.getChunkSectionMinHeight(index);
|
||||||
return this.chunk.getSections()[index].bottomBlockY() * 16;
|
break;
|
||||||
}
|
}
|
||||||
#elif MC_1_17_1
|
}
|
||||||
if (!sections[index].isEmpty())
|
|
||||||
|
return this.minNonEmptyHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMaxNonEmptyHeight()
|
||||||
{
|
{
|
||||||
// convert from an index to a block coordinate
|
if (this.maxNonEmptyHeight != Integer.MAX_VALUE)
|
||||||
return this.chunk.getSections()[index].bottomBlockY() * 16;
|
{
|
||||||
|
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--)
|
||||||
|
{
|
||||||
|
// update at each position to fix using the max height if the chunk is empty
|
||||||
|
this.maxNonEmptyHeight = this.getChunkSectionMinHeight(index) + 16;
|
||||||
|
|
||||||
|
if (sections[index] == null)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isChunkSectionEmpty(sections[index]))
|
||||||
|
{
|
||||||
|
// non-empty section found
|
||||||
|
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
|
#else
|
||||||
if (!sections[index].hasOnlyAir())
|
return section.hasOnlyAir();
|
||||||
{
|
|
||||||
// convert from an index to a block coordinate
|
|
||||||
return this.chunk.getSectionYFromSectionIndex(index) * 16;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
return Integer.MAX_VALUE;
|
private int getChunkSectionMinHeight(int index) { return (index * 16) + this.getMinBuildHeight(); }
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -206,19 +260,18 @@ public class ChunkWrapper implements IChunkWrapper
|
|||||||
public int getLightBlockingHeightMapValue(int xRel, int zRel) { return this.chunk.getOrCreateHeightmapUnprimed(Heightmap.Types.MOTION_BLOCKING).getFirstAvailable(xRel, zRel); }
|
public int getLightBlockingHeightMapValue(int xRel, int zRel) { return this.chunk.getOrCreateHeightmapUnprimed(Heightmap.Types.MOTION_BLOCKING).getFirstAvailable(xRel, zRel); }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IBiomeWrapper getBiome(int relX, int relY, int relZ)
|
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(
|
return BiomeWrapper.getBiomeWrapper(this.chunk.getBiomes().getNoiseBiome(
|
||||||
relX >> 2, relY >> 2, relZ >> 2),
|
relX >> 2, relY >> 2, relZ >> 2),
|
||||||
this.wrappedLevel);
|
this.wrappedLevel);
|
||||||
#elif PRE_MC_1_18_2
|
#elif MC_VER < MC_1_18_2
|
||||||
return BiomeWrapper.getBiomeWrapper(this.chunk.getBiomes().getNoiseBiome(
|
return BiomeWrapper.getBiomeWrapper(this.chunk.getBiomes().getNoiseBiome(
|
||||||
QuartPos.fromBlock(relX), QuartPos.fromBlock(relY), QuartPos.fromBlock(relZ)),
|
QuartPos.fromBlock(relX), QuartPos.fromBlock(relY), QuartPos.fromBlock(relZ)),
|
||||||
this.wrappedLevel);
|
this.wrappedLevel);
|
||||||
#elif PRE_MC_1_18_2
|
#elif MC_VER < MC_1_18_2
|
||||||
return BiomeWrapper.getBiomeWrapper(this.chunk.getNoiseBiome(
|
return BiomeWrapper.getBiomeWrapper(this.chunk.getNoiseBiome(
|
||||||
QuartPos.fromBlock(relX), QuartPos.fromBlock(relY), QuartPos.fromBlock(relZ)),
|
QuartPos.fromBlock(relX), QuartPos.fromBlock(relY), QuartPos.fromBlock(relZ)),
|
||||||
this.wrappedLevel);
|
this.wrappedLevel);
|
||||||
@@ -230,11 +283,35 @@ public class ChunkWrapper implements IChunkWrapper
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@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);
|
||||||
|
blockPos.setY(relY);
|
||||||
|
blockPos.setZ(relZ);
|
||||||
|
|
||||||
|
return BlockStateWrapper.fromBlockState(this.chunk.getBlockState(blockPos), this.wrappedLevel);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DhChunkPos getChunkPos() { return this.chunkPos; }
|
public DhChunkPos getChunkPos() { return this.chunkPos; }
|
||||||
|
|
||||||
public ChunkAccess getChunk() { return this.chunk; }
|
public ChunkAccess getChunk() { return this.chunk; }
|
||||||
|
|
||||||
|
public ChunkStatus getStatus() { return getStatus(this.getChunk()); }
|
||||||
|
public static ChunkStatus getStatus(ChunkAccess chunk)
|
||||||
|
{
|
||||||
|
#if MC_VER < MC_1_21
|
||||||
|
return chunk.getStatus();
|
||||||
|
#else
|
||||||
|
return chunk.getPersistedStatus();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getMaxBlockX() { return this.chunk.getPos().getMaxBlockX(); }
|
public int getMaxBlockX() { return this.chunk.getPos().getMaxBlockX(); }
|
||||||
@Override
|
@Override
|
||||||
@@ -244,8 +321,11 @@ public class ChunkWrapper implements IChunkWrapper
|
|||||||
@Override
|
@Override
|
||||||
public int getMinBlockZ() { return this.chunk.getPos().getMinBlockZ(); }
|
public int getMinBlockZ() { return this.chunk.getPos().getMinBlockZ(); }
|
||||||
|
|
||||||
@Override
|
|
||||||
public long getLongChunkPos() { return this.chunk.getPos().toLong(); }
|
|
||||||
|
//==========//
|
||||||
|
// lighting //
|
||||||
|
//==========//
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setIsDhLightCorrect(boolean isDhLightCorrect) { this.isDhLightCorrect = isDhLightCorrect; }
|
public void setIsDhLightCorrect(boolean isDhLightCorrect) { this.isDhLightCorrect = isDhLightCorrect; }
|
||||||
@@ -253,8 +333,6 @@ public class ChunkWrapper implements IChunkWrapper
|
|||||||
@Override
|
@Override
|
||||||
public void setUseDhLighting(boolean useDhLighting) { this.useDhLighting = useDhLighting; }
|
public void setUseDhLighting(boolean useDhLighting) { this.useDhLighting = useDhLighting; }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isLightCorrect()
|
public boolean isLightCorrect()
|
||||||
{
|
{
|
||||||
@@ -264,12 +342,11 @@ 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
|
return false; // MC's lighting engine doesn't work consistently enough to trust for 1.16 or 1.17
|
||||||
#else
|
#else
|
||||||
if (this.chunk instanceof LevelChunk)
|
if (this.chunk instanceof LevelChunk levelChunk)
|
||||||
{
|
{
|
||||||
LevelChunk levelChunk = (LevelChunk) this.chunk;
|
|
||||||
if (levelChunk.getLevel() instanceof ClientLevel)
|
if (levelChunk.getLevel() instanceof ClientLevel)
|
||||||
{
|
{
|
||||||
// connected to a server
|
// connected to a server
|
||||||
@@ -307,10 +384,11 @@ public class ChunkWrapper implements IChunkWrapper
|
|||||||
{
|
{
|
||||||
if (this.blockLightStorage == null)
|
if (this.blockLightStorage == null)
|
||||||
{
|
{
|
||||||
this.blockLightStorage = new ChunkLightStorage(this.getMinBuildHeight(), this.getMaxBuildHeight());
|
this.blockLightStorage = ChunkLightStorage.createBlockLightStorage(this);
|
||||||
}
|
}
|
||||||
return this.blockLightStorage;
|
return this.blockLightStorage;
|
||||||
}
|
}
|
||||||
|
public void setBlockLightStorage(ChunkLightStorage lightStorage) { this.blockLightStorage = lightStorage; }
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -330,10 +408,11 @@ public class ChunkWrapper implements IChunkWrapper
|
|||||||
{
|
{
|
||||||
if (this.skyLightStorage == null)
|
if (this.skyLightStorage == null)
|
||||||
{
|
{
|
||||||
this.skyLightStorage = new ChunkLightStorage(this.getMinBuildHeight(), this.getMaxBuildHeight());
|
this.skyLightStorage = ChunkLightStorage.createSkyLightStorage(this);
|
||||||
}
|
}
|
||||||
return this.skyLightStorage;
|
return this.skyLightStorage;
|
||||||
}
|
}
|
||||||
|
public void setSkyLightStorage(ChunkLightStorage lightStorage) { this.skyLightStorage = lightStorage; }
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -374,8 +453,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
|
@Override
|
||||||
public ArrayList<DhBlockPos> getBlockLightPosList()
|
public synchronized ArrayList<DhBlockPos> getBlockLightPosList()
|
||||||
{
|
{
|
||||||
// only populate the list once
|
// only populate the list once
|
||||||
if (this.blockLightPosList == null)
|
if (this.blockLightPosList == null)
|
||||||
@@ -383,22 +466,82 @@ public class ChunkWrapper implements IChunkWrapper
|
|||||||
this.blockLightPosList = new ArrayList<>();
|
this.blockLightPosList = new ArrayList<>();
|
||||||
|
|
||||||
|
|
||||||
#if PRE_MC_1_20_1
|
#if MC_VER < MC_1_20_1
|
||||||
this.chunk.getLights().forEach((blockPos) ->
|
this.chunk.getLights().forEach((blockPos) ->
|
||||||
{
|
{
|
||||||
this.blockLightPosList.add(new DhBlockPos(blockPos.getX(), blockPos.getY(), blockPos.getZ()));
|
this.blockLightPosList.add(new DhBlockPos(blockPos.getX(), blockPos.getY(), blockPos.getZ()));
|
||||||
});
|
});
|
||||||
#else
|
#else
|
||||||
this.chunk.findBlockLightSources((blockPos, blockState) ->
|
this.chunk.findBlockLightSources((blockPos, blockState) ->
|
||||||
{
|
this.blockLightPosList.add(new DhBlockPos(blockPos.getX(), blockPos.getY(), blockPos.getZ())));
|
||||||
this.blockLightPosList.add(new DhBlockPos(blockPos.getX(), blockPos.getY(), blockPos.getZ()));
|
|
||||||
});
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.blockLightPosList;
|
return this.blockLightPosList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void syncedUpdateClientLightStatus()
|
||||||
|
{
|
||||||
|
#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,
|
||||||
|
// clear it to prevent memory leaks
|
||||||
|
chunksNeedingClientLightUpdating.clear();
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
// update the chunks client lighting
|
||||||
|
ChunkWrapper chunkWrapper = chunksNeedingClientLightUpdating.poll();
|
||||||
|
while (chunkWrapper != null)
|
||||||
|
{
|
||||||
|
chunkWrapper.updateIsClientLightingCorrect();
|
||||||
|
chunkWrapper = chunksNeedingClientLightUpdating.poll();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
/** Should be called after client light updates are triggered. */
|
||||||
|
private void updateIsClientLightingCorrect()
|
||||||
|
{
|
||||||
|
if (this.chunk instanceof LevelChunk levelChunk && ((LevelChunk) this.chunk).getLevel() instanceof ClientLevel)
|
||||||
|
{
|
||||||
|
ClientChunkCache clientChunkCache = ((ClientLevel) levelChunk.getLevel()).getChunkSource();
|
||||||
|
this.isMcClientLightingCorrect = clientChunkCache.getChunkForLighting(this.chunk.getPos().x, this.chunk.getPos().z) != null &&
|
||||||
|
#if MC_VER <= MC_1_17_1
|
||||||
|
levelChunk.isLightCorrect();
|
||||||
|
#elif MC_VER < MC_1_20_1
|
||||||
|
levelChunk.isClientLightReady();
|
||||||
|
#else
|
||||||
|
checkLightSectionsOnChunk(levelChunk, levelChunk.getLevel().getLightEngine());
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#if MC_VER >= MC_1_20_1
|
||||||
|
private static boolean checkLightSectionsOnChunk(LevelChunk chunk, LevelLightEngine engine)
|
||||||
|
{
|
||||||
|
LevelChunkSection[] sections = chunk.getSections();
|
||||||
|
int minY = chunk.getMinSection();
|
||||||
|
int maxY = chunk.getMaxSection();
|
||||||
|
for (int y = minY; y < maxY; ++y)
|
||||||
|
{
|
||||||
|
LevelChunkSection section = sections[chunk.getSectionIndexFromSectionY(y)];
|
||||||
|
if (section.hasOnlyAir()) continue;
|
||||||
|
if (!engine.lightOnInSection(SectionPos.of(chunk.getPos(), y)))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//===============//
|
||||||
|
// other methods //
|
||||||
|
//===============//
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean doNearbyChunksExist()
|
public boolean doNearbyChunksExist()
|
||||||
{
|
{
|
||||||
@@ -425,146 +568,27 @@ public class ChunkWrapper implements IChunkWrapper
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public LevelReader getColorResolver() { return this.lightSource; }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() { return this.chunk.getClass().getSimpleName() + this.chunk.getPos(); }
|
|
||||||
|
|
||||||
@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);
|
|
||||||
blockPos.setY(relY);
|
|
||||||
blockPos.setZ(relZ);
|
|
||||||
|
|
||||||
return BlockStateWrapper.fromBlockState(this.chunk.getBlockState(blockPos), this.wrappedLevel);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isStillValid() { return this.wrappedLevel.tryGetChunk(this.chunkPos) == this; }
|
public boolean isStillValid() { return this.wrappedLevel.tryGetChunk(this.chunkPos) == this; }
|
||||||
|
|
||||||
|
|
||||||
public static void syncedUpdateClientLightStatus()
|
|
||||||
{
|
|
||||||
#if PRE_MC_1_18_2
|
|
||||||
// TODO: Check what to do in 1.18.1 and older
|
|
||||||
|
|
||||||
// since we don't currently handle this list,
|
|
||||||
// clear it to prevent memory leaks
|
|
||||||
chunksNeedingClientLightUpdating.clear();
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
// update the chunks client lighting
|
|
||||||
ChunkWrapper chunkWrapper = chunksNeedingClientLightUpdating.poll();
|
|
||||||
while (chunkWrapper != null)
|
|
||||||
{
|
|
||||||
chunkWrapper.updateIsClientLightingCorrect();
|
|
||||||
chunkWrapper = chunksNeedingClientLightUpdating.poll();
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
/** Should be called after client light updates are triggered. */
|
|
||||||
private void updateIsClientLightingCorrect()
|
|
||||||
{
|
|
||||||
if (this.chunk instanceof LevelChunk && ((LevelChunk) this.chunk).getLevel() instanceof ClientLevel)
|
|
||||||
{
|
|
||||||
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
|
|
||||||
levelChunk.isLightCorrect();
|
|
||||||
#elif PRE_MC_1_20_1
|
|
||||||
levelChunk.isClientLightReady();
|
|
||||||
#else
|
|
||||||
checkLightSectionsOnChunk(levelChunk, levelChunk.getLevel().getLightEngine());
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#if POST_MC_1_20_1
|
|
||||||
private static boolean checkLightSectionsOnChunk(LevelChunk chunk, LevelLightEngine engine)
|
|
||||||
{
|
|
||||||
LevelChunkSection[] sections = chunk.getSections();
|
|
||||||
int minY = chunk.getMinSection();
|
|
||||||
int maxY = chunk.getMaxSection();
|
|
||||||
for (int y = minY; y < maxY; ++y)
|
|
||||||
{
|
|
||||||
LevelChunkSection section = sections[chunk.getSectionIndexFromSectionY(y)];
|
|
||||||
if (section.hasOnlyAir()) continue;
|
|
||||||
if (!engine.lightOnInSection(SectionPos.of(chunk.getPos(), y)))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//================//
|
//================//
|
||||||
// helper methods //
|
// base overrides //
|
||||||
//================//
|
//================//
|
||||||
|
|
||||||
/** used to prevent accidentally attempting to get/set values outside this chunk's boundaries */
|
@Override
|
||||||
private void throwIndexOutOfBoundsIfRelativePosOutsideChunkBounds(int x, int y, int z) throws IndexOutOfBoundsException
|
public String toString() { return this.chunk.getClass().getSimpleName() + this.chunk.getPos(); }
|
||||||
{
|
|
||||||
if (!RUN_RELATIVE_POS_INDEX_VALIDATION)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// FIXME +1 is to handle the fact that LodDataBuilder adds +1 to all block lighting calculations, also done in the constructor
|
|
||||||
int minHeight = this.getMinBuildHeight();
|
|
||||||
int maxHeight = this.getMaxBuildHeight() + 1;
|
|
||||||
|
|
||||||
if (x < 0 || x >= LodUtil.CHUNK_WIDTH
|
|
||||||
|| z < 0 || z >= LodUtil.CHUNK_WIDTH
|
|
||||||
|| y < minHeight || y > maxHeight)
|
|
||||||
{
|
|
||||||
String errorMessage = "Relative position [" + x + "," + y + "," + z + "] out of bounds. \n" +
|
|
||||||
"X/Z must be between 0 and 15 (inclusive) \n" +
|
|
||||||
"Y must be between [" + minHeight + "] and [" + maxHeight + "] (inclusive).";
|
|
||||||
throw new IndexOutOfBoundsException(errorMessage);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Converts a 3D position into a 1D array index. <br><br>
|
|
||||||
*
|
|
||||||
* Source: <br>
|
|
||||||
* <a href="https://stackoverflow.com/questions/7367770/how-to-flatten-or-index-3d-array-in-1d-array">stackoverflow</a>
|
|
||||||
*/
|
|
||||||
public int relativeBlockPosToIndex(int xRel, int y, int zRel)
|
|
||||||
{
|
|
||||||
int yRel = y - this.getMinBuildHeight();
|
|
||||||
return (zRel * LodUtil.CHUNK_WIDTH * this.getHeight()) + (yRel * LodUtil.CHUNK_WIDTH) + xRel;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Converts a 3D position into a 1D array index. <br><br>
|
|
||||||
*
|
|
||||||
* Source: <br>
|
|
||||||
* <a href="https://stackoverflow.com/questions/7367770/how-to-flatten-or-index-3d-array-in-1d-array">stackoverflow</a>
|
|
||||||
*/
|
|
||||||
public DhBlockPos indexToRelativeBlockPos(int index)
|
|
||||||
{
|
|
||||||
final int zRel = index / (LodUtil.CHUNK_WIDTH * this.getHeight());
|
|
||||||
index -= (zRel * LodUtil.CHUNK_WIDTH * this.getHeight());
|
|
||||||
|
|
||||||
final int y = index / LodUtil.CHUNK_WIDTH;
|
|
||||||
final int yRel = y + this.getMinBuildHeight();
|
|
||||||
|
|
||||||
final int xRel = index % LodUtil.CHUNK_WIDTH;
|
|
||||||
return new DhBlockPos(xRel, yRel, zRel);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
//@Override
|
||||||
|
//public int hashCode()
|
||||||
|
//{
|
||||||
|
// if (this.blockBiomeHashCode == 0)
|
||||||
|
// {
|
||||||
|
// this.blockBiomeHashCode = this.getBlockBiomeHashCode();
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// return this.blockBiomeHashCode;
|
||||||
|
//}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+58
-36
@@ -16,7 +16,7 @@ import java.util.regex.Pattern;
|
|||||||
// Logger (for debug stuff)
|
// Logger (for debug stuff)
|
||||||
|
|
||||||
import com.seibel.distanthorizons.api.enums.config.DisallowSelectingViaConfigGui;
|
import com.seibel.distanthorizons.api.enums.config.DisallowSelectingViaConfigGui;
|
||||||
import com.seibel.distanthorizons.api.enums.config.EUpdateBranch;
|
import com.seibel.distanthorizons.api.enums.config.EDhApiUpdateBranch;
|
||||||
import com.seibel.distanthorizons.core.config.Config;
|
import com.seibel.distanthorizons.core.config.Config;
|
||||||
import com.seibel.distanthorizons.core.config.ConfigBase;
|
import com.seibel.distanthorizons.core.config.ConfigBase;
|
||||||
import com.seibel.distanthorizons.core.config.types.*;
|
import com.seibel.distanthorizons.core.config.types.*;
|
||||||
@@ -35,7 +35,7 @@ import com.seibel.distanthorizons.coreapi.ModInfo;
|
|||||||
import net.minecraft.ChatFormatting;
|
import net.minecraft.ChatFormatting;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.gui.Font;
|
import net.minecraft.client.gui.Font;
|
||||||
#if PRE_MC_1_20_1
|
#if MC_VER < MC_1_20_1
|
||||||
import com.mojang.blaze3d.vertex.PoseStack;
|
import com.mojang.blaze3d.vertex.PoseStack;
|
||||||
import net.minecraft.client.gui.GuiComponent;
|
import net.minecraft.client.gui.GuiComponent;
|
||||||
#else
|
#else
|
||||||
@@ -49,7 +49,7 @@ import net.minecraft.client.gui.components.events.GuiEventListener;
|
|||||||
import net.minecraft.client.gui.screens.Screen;
|
import net.minecraft.client.gui.screens.Screen;
|
||||||
import net.minecraft.network.chat.Component;
|
import net.minecraft.network.chat.Component;
|
||||||
import net.minecraft.client.resources.language.I18n; // translation
|
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;
|
import net.minecraft.client.gui.narration.NarratableEntry;
|
||||||
#endif
|
#endif
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
@@ -98,6 +98,7 @@ public class ClassicConfigGUI
|
|||||||
public static final int SpaceFromRightScreen = 10;
|
public static final int SpaceFromRightScreen = 10;
|
||||||
public static final int ButtonWidthSpacing = 5;
|
public static final int ButtonWidthSpacing = 5;
|
||||||
public static final int ResetButtonWidth = 40;
|
public static final int ResetButtonWidth = 40;
|
||||||
|
public static final int ResetButtonHeight = 20;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -144,9 +145,9 @@ public class ClassicConfigGUI
|
|||||||
case 0:
|
case 0:
|
||||||
((EntryInfo) info.guiValue).error = null; break;
|
((EntryInfo) info.guiValue).error = null; break;
|
||||||
case -1:
|
case -1:
|
||||||
((EntryInfo) info.guiValue).error = new AbstractMap.SimpleEntry<>(editBox, TextOrTranslatable("§cMinimum length is " + ((ConfigEntry) info).getMin())); break;
|
((EntryInfo) info.guiValue).error = new AbstractMap.SimpleEntry<>(editBox, TextOrTranslatable("§cMinimum length is " + ((ConfigEntry<?>) info).getMin())); break;
|
||||||
case 1:
|
case 1:
|
||||||
((EntryInfo) info.guiValue).error = new AbstractMap.SimpleEntry<>(editBox, TextOrTranslatable("§cMaximum length is " + ((ConfigEntry) info).getMax())); break;
|
((EntryInfo) info.guiValue).error = new AbstractMap.SimpleEntry<>(editBox, TextOrTranslatable("§cMaximum length is " + ((ConfigEntry<?>) info).getMax())); break;
|
||||||
case 2:
|
case 2:
|
||||||
((EntryInfo) info.guiValue).error = new AbstractMap.SimpleEntry<>(editBox, TextOrTranslatable("§cValue is invalid")); break;
|
((EntryInfo) info.guiValue).error = new AbstractMap.SimpleEntry<>(editBox, TextOrTranslatable("§cValue is invalid")); break;
|
||||||
}
|
}
|
||||||
@@ -157,19 +158,22 @@ public class ClassicConfigGUI
|
|||||||
// button.active = entries.stream().allMatch(e -> e.inLimits);
|
// button.active = entries.stream().allMatch(e -> e.inLimits);
|
||||||
|
|
||||||
|
|
||||||
if (((ConfigEntry) info).isValid(value) == 0 && info.getType() != List.class)
|
if (info.getType() == String.class
|
||||||
|
|| info.getType() == List.class)
|
||||||
|
{
|
||||||
|
((ConfigEntry) info).uiSetWithoutSaving(stringValue);
|
||||||
|
}
|
||||||
|
else if (((ConfigEntry) info).isValid(value) == 0)
|
||||||
{
|
{
|
||||||
if (!cast)
|
if (!cast)
|
||||||
|
{
|
||||||
((ConfigEntry) info).uiSetWithoutSaving(value);
|
((ConfigEntry) info).uiSetWithoutSaving(value);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
((ConfigEntry) info).uiSetWithoutSaving(value.intValue());
|
((ConfigEntry) info).uiSetWithoutSaving(value.intValue());
|
||||||
}
|
}
|
||||||
// else if (((ConfigEntry) info).isValidMemoryAddress() == 0)
|
}
|
||||||
// {
|
|
||||||
// if (((List<String>) info.get()).size() == ((EntryInfo) info.guiValue).index)
|
|
||||||
// info.uiSet(((List<String>) info.get()).add(""));
|
|
||||||
// info.uiSet(((List<String>) info.get()).set(((EntryInfo) info.guiValue).index, Arrays.stream(((EntryInfo) info.guiValue).tempValue.replace("[", "").replace("]", "").split(", ")).collect(Collectors.toList()).get(0)));
|
|
||||||
// }
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
@@ -231,7 +235,7 @@ public class ClassicConfigGUI
|
|||||||
ConfigBase.INSTANCE.configFileINSTANCE.saveToFile();
|
ConfigBase.INSTANCE.configFileINSTANCE.saveToFile();
|
||||||
Objects.requireNonNull(this.minecraft).setScreen(this.parent);
|
Objects.requireNonNull(this.minecraft).setScreen(this.parent);
|
||||||
|
|
||||||
CONFIG_CORE_INTERFACE.onScreenChangeListenerList.forEach((listener) -> listener.run());
|
CONFIG_CORE_INTERFACE.onScreenChangeListenerList.forEach(Runnable::run);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -244,17 +248,23 @@ public class ClassicConfigGUI
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Changelog button
|
// Changelog button
|
||||||
if (Config.Client.Advanced.AutoUpdater.enableAutoUpdater.get() && Config.Client.Advanced.AutoUpdater.updateBranch.get() == EUpdateBranch.STABLE)
|
if (Config.Client.Advanced.AutoUpdater.enableAutoUpdater.get() && !ModInfo.IS_DEV_BUILD) // we only have changelogs for stable builds
|
||||||
{
|
{
|
||||||
this.addBtn(new TexturedButtonWidget(
|
this.addBtn(new TexturedButtonWidget(
|
||||||
// Where the button is on the screen
|
// Where the button is on the screen
|
||||||
this.width - 28, this.height - 28,
|
this.width - 28, this.height - 28,
|
||||||
// Width and height of the button
|
// Width and height of the button
|
||||||
20, 20,
|
20, 20,
|
||||||
// Offset
|
// texture UV Offset
|
||||||
0, 0,
|
0, 0,
|
||||||
// Some textuary stuff
|
// Some textuary stuff
|
||||||
0, new ResourceLocation(ModInfo.ID, "textures/gui/changelog.png"), 20, 20,
|
0,
|
||||||
|
#if MC_VER < MC_1_21
|
||||||
|
new ResourceLocation(ModInfo.ID, "textures/gui/changelog.png"),
|
||||||
|
#else
|
||||||
|
ResourceLocation.fromNamespaceAndPath(ModInfo.ID, "textures/gui/changelog.png"),
|
||||||
|
#endif
|
||||||
|
20, 20,
|
||||||
// Create the button and tell it where to go
|
// Create the button and tell it where to go
|
||||||
(buttonWidget) -> {
|
(buttonWidget) -> {
|
||||||
ChangelogScreen changelogScreen = new ChangelogScreen(this);
|
ChangelogScreen changelogScreen = new ChangelogScreen(this);
|
||||||
@@ -269,7 +279,11 @@ public class ClassicConfigGUI
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
addBtn(MakeBtn(Translatable("distanthorizons.general.cancel"), this.width / 2 - 154, this.height - 28, 150, 20, button -> {
|
addBtn(MakeBtn(Translatable("distanthorizons.general.cancel"),
|
||||||
|
this.width / 2 - 154, this.height - 28,
|
||||||
|
150, 20,
|
||||||
|
button ->
|
||||||
|
{
|
||||||
ConfigBase.INSTANCE.configFileINSTANCE.loadFromFile();
|
ConfigBase.INSTANCE.configFileINSTANCE.loadFromFile();
|
||||||
Objects.requireNonNull(minecraft).setScreen(parent);
|
Objects.requireNonNull(minecraft).setScreen(parent);
|
||||||
}));
|
}));
|
||||||
@@ -278,9 +292,12 @@ public class ClassicConfigGUI
|
|||||||
Objects.requireNonNull(minecraft).setScreen(parent);
|
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 MC_VER < MC_1_20_6 // no background is rendered in MC 1.20.6+
|
||||||
if (this.minecraft != null && this.minecraft.level != null)
|
if (this.minecraft != null && this.minecraft.level != null)
|
||||||
this.list.setRenderBackground(false);
|
this.list.setRenderBackground(false);
|
||||||
|
#endif
|
||||||
|
|
||||||
this.addWidget(this.list);
|
this.addWidget(this.list);
|
||||||
|
|
||||||
@@ -302,7 +319,7 @@ public class ClassicConfigGUI
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
CONFIG_CORE_INTERFACE.onScreenChangeListenerList.forEach((listener) -> listener.run());
|
CONFIG_CORE_INTERFACE.onScreenChangeListenerList.forEach(Runnable::run);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -311,20 +328,21 @@ public class ClassicConfigGUI
|
|||||||
initEntry(info, this.translationPrefix);
|
initEntry(info, this.translationPrefix);
|
||||||
Component name = Translatable(translationPrefix + info.getNameWCategory());
|
Component name = Translatable(translationPrefix + info.getNameWCategory());
|
||||||
|
|
||||||
|
|
||||||
if (ConfigEntry.class.isAssignableFrom(info.getClass()))
|
if (ConfigEntry.class.isAssignableFrom(info.getClass()))
|
||||||
{
|
{
|
||||||
Button.OnPress btnAction = button -> {
|
Button.OnPress btnAction = button -> {
|
||||||
((ConfigEntry) info).uiSetWithoutSaving(((ConfigEntry) info).getDefaultValue());
|
((ConfigEntry) info).uiSetWithoutSaving(((ConfigEntry<?>) info).getDefaultValue());
|
||||||
((EntryInfo) info.guiValue).index = 0;
|
((EntryInfo) info.guiValue).index = 0;
|
||||||
this.reload = true;
|
this.reload = true;
|
||||||
Objects.requireNonNull(minecraft).setScreen(this);
|
Objects.requireNonNull(minecraft).setScreen(this);
|
||||||
};
|
};
|
||||||
int a = this.width - ConfigScreenConfigs.SpaceFromRightScreen - 150 - ConfigScreenConfigs.ButtonWidthSpacing - ConfigScreenConfigs.ResetButtonWidth;
|
int posX = this.width - ConfigScreenConfigs.SpaceFromRightScreen - 150 - ConfigScreenConfigs.ButtonWidthSpacing - ConfigScreenConfigs.ResetButtonWidth;
|
||||||
int b = 0;
|
int posZ = 0;
|
||||||
int c = ConfigScreenConfigs.ResetButtonWidth;
|
|
||||||
int d = 20;
|
|
||||||
|
|
||||||
Button resetButton = MakeBtn(Translatable("distanthorizons.general.reset").withStyle(ChatFormatting.RED), a, b, c, d, btnAction);
|
Button resetButton = MakeBtn(Translatable("distanthorizons.general.reset").withStyle(ChatFormatting.RED),
|
||||||
|
posX, posZ, ConfigScreenConfigs.ResetButtonWidth, ConfigScreenConfigs.ResetButtonHeight,
|
||||||
|
btnAction);
|
||||||
|
|
||||||
if (((EntryInfo) info.guiValue).widget instanceof Map.Entry)
|
if (((EntryInfo) info.guiValue).widget instanceof Map.Entry)
|
||||||
{
|
{
|
||||||
@@ -358,9 +376,7 @@ public class ClassicConfigGUI
|
|||||||
}
|
}
|
||||||
if (ConfigUIButton.class.isAssignableFrom(info.getClass()))
|
if (ConfigUIButton.class.isAssignableFrom(info.getClass()))
|
||||||
{
|
{
|
||||||
Button widget = MakeBtn(name, this.width / 2 - 100, this.height - 28, 100 * 2, 20, (button -> {
|
Button widget = MakeBtn(name, this.width / 2 - 100, this.height - 28, 100 * 2, 20, (button -> ((ConfigUIButton) info).runAction()));
|
||||||
((ConfigUIButton) info).runAction();
|
|
||||||
}));
|
|
||||||
this.list.addButton(widget, null, null, null);
|
this.list.addButton(widget, null, null, null);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -379,13 +395,13 @@ public class ClassicConfigGUI
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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)
|
public void render(PoseStack matrices, int mouseX, int mouseY, float delta)
|
||||||
#else
|
#else
|
||||||
public void render(GuiGraphics matrices, int mouseX, int mouseY, float delta)
|
public void render(GuiGraphics matrices, int mouseX, int mouseY, float delta)
|
||||||
#endif
|
#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
|
this.renderBackground(matrices); // Renders background
|
||||||
#else
|
#else
|
||||||
super.render(matrices, mouseX, mouseY, delta);
|
super.render(matrices, mouseX, mouseY, delta);
|
||||||
@@ -428,7 +444,9 @@ public class ClassicConfigGUI
|
|||||||
String key = translationPrefix + (newInfo.category.isEmpty() ? "" : newInfo.category + ".") + newInfo.getName() + ".@tooltip";
|
String key = translationPrefix + (newInfo.category.isEmpty() ? "" : newInfo.category + ".") + newInfo.getName() + ".@tooltip";
|
||||||
|
|
||||||
if (((EntryInfo) newInfo.guiValue).error != null && text.equals(name))
|
if (((EntryInfo) newInfo.guiValue).error != null && text.equals(name))
|
||||||
|
{
|
||||||
DhRenderTooltip(matrices, font, ((EntryInfo) newInfo.guiValue).error.getValue(), mouseX, mouseY);
|
DhRenderTooltip(matrices, font, ((EntryInfo) newInfo.guiValue).error.getValue(), mouseX, mouseY);
|
||||||
|
}
|
||||||
else if (I18n.exists(key) && (text != null && text.equals(name)))
|
else if (I18n.exists(key) && (text != null && text.equals(name)))
|
||||||
{
|
{
|
||||||
List<Component> list = new ArrayList<>();
|
List<Component> list = new ArrayList<>();
|
||||||
@@ -441,7 +459,7 @@ public class ClassicConfigGUI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#if PRE_MC_1_20_2
|
#if MC_VER < MC_1_20_2
|
||||||
super.render(matrices, mouseX, mouseY, delta);
|
super.render(matrices, mouseX, mouseY, delta);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -537,9 +555,13 @@ public class ClassicConfigGUI
|
|||||||
{
|
{
|
||||||
Font textRenderer;
|
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;
|
this.centerListVertically = false;
|
||||||
textRenderer = minecraftClient.font;
|
textRenderer = minecraftClient.font;
|
||||||
}
|
}
|
||||||
@@ -601,7 +623,7 @@ public class ClassicConfigGUI
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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)
|
public void render(PoseStack matrices, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean hovered, float tickDelta)
|
||||||
#else
|
#else
|
||||||
public void render(GuiGraphics matrices, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean hovered, float tickDelta)
|
public void render(GuiGraphics matrices, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean hovered, float tickDelta)
|
||||||
@@ -623,7 +645,7 @@ public class ClassicConfigGUI
|
|||||||
indexButton.render(matrices, mouseX, mouseY, tickDelta);
|
indexButton.render(matrices, mouseX, mouseY, tickDelta);
|
||||||
}
|
}
|
||||||
if (text != null && (!text.getString().contains("spacer") || button != null))
|
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);
|
GuiComponent.drawString(matrices, textRenderer, text, 12, y + 5, 0xFFFFFF);
|
||||||
#else
|
#else
|
||||||
matrices.drawString(textRenderer, text, 12, y + 5, 0xFFFFFF);
|
matrices.drawString(textRenderer, text, 12, y + 5, 0xFFFFFF);
|
||||||
@@ -638,7 +660,7 @@ public class ClassicConfigGUI
|
|||||||
|
|
||||||
// Only for 1.17 and over
|
// Only for 1.17 and over
|
||||||
// Remove in 1.16 and below
|
// Remove in 1.16 and below
|
||||||
#if POST_MC_1_17_1
|
#if MC_VER >= MC_1_17_1
|
||||||
@Override
|
@Override
|
||||||
public List<? extends NarratableEntry> narratables()
|
public List<? extends NarratableEntry> narratables()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package com.seibel.distanthorizons.common.wrappers.gui;
|
package com.seibel.distanthorizons.common.wrappers.gui;
|
||||||
|
|
||||||
import net.minecraft.client.gui.Font;
|
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 com.mojang.blaze3d.vertex.PoseStack;
|
||||||
#else
|
#else
|
||||||
import net.minecraft.client.gui.GuiGraphics;
|
import net.minecraft.client.gui.GuiGraphics;
|
||||||
@@ -24,14 +24,14 @@ public class DhScreen extends Screen
|
|||||||
// addButton in 1.16 and below
|
// addButton in 1.16 and below
|
||||||
protected Button addBtn(Button button)
|
protected Button addBtn(Button button)
|
||||||
{
|
{
|
||||||
#if PRE_MC_1_17_1
|
#if MC_VER < MC_1_17_1
|
||||||
return this.addButton(button);
|
return this.addButton(button);
|
||||||
#else
|
#else
|
||||||
return this.addRenderableWidget(button);
|
return this.addRenderableWidget(button);
|
||||||
#endif
|
#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)
|
protected void DhDrawCenteredString(PoseStack guiStack, Font font, Component text, int x, int y, int color)
|
||||||
{
|
{
|
||||||
drawCenteredString(guiStack, font, text, x, y, color);
|
drawCenteredString(guiStack, font, text, x, y, color);
|
||||||
|
|||||||
+9
-10
@@ -25,19 +25,18 @@ public class GetConfigScreen
|
|||||||
// This shouldn't be here, but I need a way to test it after Minecraft inits its assets
|
// This shouldn't be here, but I need a way to test it after Minecraft inits its assets
|
||||||
//System.out.println(ConfigBase.INSTANCE.generateLang(false, true));
|
//System.out.println(ConfigBase.INSTANCE.generateLang(false, true));
|
||||||
|
|
||||||
switch (useScreen)
|
return switch (useScreen)
|
||||||
|
{
|
||||||
|
case Classic -> ClassicConfigGUI.getScreen(ConfigBase.INSTANCE, parent, "client");
|
||||||
|
case OpenGL ->
|
||||||
{
|
{
|
||||||
case Classic:
|
|
||||||
return ClassicConfigGUI.getScreen(ConfigBase.INSTANCE, parent, "client");
|
|
||||||
case OpenGL:
|
|
||||||
MinecraftScreen.getScreen(parent, new OpenGLConfigScreen(), ModInfo.ID + ".title");
|
MinecraftScreen.getScreen(parent, new OpenGLConfigScreen(), ModInfo.ID + ".title");
|
||||||
return null;
|
yield null;
|
||||||
// case JavaFX -> MinecraftScreen.getScreen(parent, new JavaScreenHandlerScreen(new JavaScreenHandlerScreen.ExampleScreen()), ModInfo.ID + ".title");
|
|
||||||
case JavaFX:
|
|
||||||
return MinecraftScreen.getScreen(parent, new JavaScreenHandlerScreen(new ConfigScreen()), ModInfo.ID + ".title");
|
|
||||||
default:
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
// case JavaFX -> MinecraftScreen.getScreen(parent, new JavaScreenHandlerScreen(new JavaScreenHandlerScreen.ExampleScreen()), ModInfo.ID + ".title");
|
||||||
|
case JavaFX -> MinecraftScreen.getScreen(parent, new JavaScreenHandlerScreen(new ConfigScreen()), ModInfo.ID + ".title");
|
||||||
|
default -> throw new IllegalArgumentException("No config screen implementation defined for [" + useScreen + "].");
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
+10
-10
@@ -5,7 +5,7 @@ import net.minecraft.client.gui.components.Button;
|
|||||||
import net.minecraft.network.chat.Component;
|
import net.minecraft.network.chat.Component;
|
||||||
import net.minecraft.network.chat.MutableComponent;
|
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.TextComponent;
|
||||||
import net.minecraft.network.chat.TranslatableComponent;
|
import net.minecraft.network.chat.TranslatableComponent;
|
||||||
#endif
|
#endif
|
||||||
@@ -15,18 +15,18 @@ public class GuiHelper
|
|||||||
/**
|
/**
|
||||||
* Helper static methods for versional compat
|
* Helper static methods for versional compat
|
||||||
*/
|
*/
|
||||||
public static Button MakeBtn(Component base, int a, int b, int c, int d, Button.OnPress action)
|
public static Button MakeBtn(Component base, int posX, int posZ, int width, int height, 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);
|
return new Button(posX, posZ, width, height, base, action);
|
||||||
#else
|
#else
|
||||||
return Button.builder(base, action).bounds(a, b, c, d).build();
|
return Button.builder(base, action).bounds(posX, posZ, width, height).build();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
public static MutableComponent TextOrLiteral(String text)
|
public static MutableComponent TextOrLiteral(String text)
|
||||||
{
|
{
|
||||||
#if PRE_MC_1_19_2
|
#if MC_VER < MC_1_19_2
|
||||||
return new TextComponent(text);
|
return new TextComponent(text);
|
||||||
#else
|
#else
|
||||||
return Component.literal(text);
|
return Component.literal(text);
|
||||||
@@ -35,7 +35,7 @@ public class GuiHelper
|
|||||||
|
|
||||||
public static MutableComponent TextOrTranslatable(String text)
|
public static MutableComponent TextOrTranslatable(String text)
|
||||||
{
|
{
|
||||||
#if PRE_MC_1_19_2
|
#if MC_VER < MC_1_19_2
|
||||||
return new TextComponent(text);
|
return new TextComponent(text);
|
||||||
#else
|
#else
|
||||||
return Component.translatable(text);
|
return Component.translatable(text);
|
||||||
@@ -44,7 +44,7 @@ public class GuiHelper
|
|||||||
|
|
||||||
public static MutableComponent Translatable(String text, Object... args)
|
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);
|
return new TranslatableComponent(text, args);
|
||||||
#else
|
#else
|
||||||
return Component.translatable(text, args);
|
return Component.translatable(text, args);
|
||||||
@@ -53,7 +53,7 @@ public class GuiHelper
|
|||||||
|
|
||||||
public static void SetX(AbstractWidget w, int x)
|
public static void SetX(AbstractWidget w, int x)
|
||||||
{
|
{
|
||||||
#if PRE_MC_1_19_4
|
#if MC_VER < MC_1_19_4
|
||||||
w.x = x;
|
w.x = x;
|
||||||
#else
|
#else
|
||||||
w.setX(x);
|
w.setX(x);
|
||||||
@@ -62,7 +62,7 @@ public class GuiHelper
|
|||||||
|
|
||||||
public static void SetY(AbstractWidget w, int y)
|
public static void SetY(AbstractWidget w, int y)
|
||||||
{
|
{
|
||||||
#if PRE_MC_1_19_4
|
#if MC_VER < MC_1_19_4
|
||||||
w.y = y;
|
w.y = y;
|
||||||
#else
|
#else
|
||||||
w.setY(y);
|
w.setY(y);
|
||||||
|
|||||||
+17
-9
@@ -4,7 +4,7 @@ import com.mojang.blaze3d.platform.Window;
|
|||||||
import com.mojang.blaze3d.vertex.PoseStack;
|
import com.mojang.blaze3d.vertex.PoseStack;
|
||||||
import com.seibel.distanthorizons.core.config.gui.AbstractScreen;
|
import com.seibel.distanthorizons.core.config.gui.AbstractScreen;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
#if POST_MC_1_20_1
|
#if MC_VER >= MC_1_20_1
|
||||||
import net.minecraft.client.gui.GuiGraphics;
|
import net.minecraft.client.gui.GuiGraphics;
|
||||||
#endif
|
#endif
|
||||||
import net.minecraft.client.gui.components.ContainerObjectSelectionList;
|
import net.minecraft.client.gui.components.ContainerObjectSelectionList;
|
||||||
@@ -28,7 +28,7 @@ public class MinecraftScreen
|
|||||||
private AbstractScreen screen;
|
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)
|
public static net.minecraft.network.chat.TranslatableComponent translate(String str, Object... args)
|
||||||
{
|
{
|
||||||
return new net.minecraft.network.chat.TranslatableComponent(str, args);
|
return new net.minecraft.network.chat.TranslatableComponent(str, args);
|
||||||
@@ -59,23 +59,27 @@ public class MinecraftScreen
|
|||||||
screen.scaledHeight = this.height;
|
screen.scaledHeight = this.height;
|
||||||
screen.init(); // Init our own config screen
|
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 MC_VER < MC_1_20_6 // no background is rendered in MC 1.20.6+
|
||||||
if (this.minecraft != null && this.minecraft.level != null) // Check if in game
|
if (this.minecraft != null && this.minecraft.level != null) // Check if in game
|
||||||
this.list.setRenderBackground(false); // Disable from rendering
|
this.list.setRenderBackground(false); // Disable from rendering
|
||||||
|
#endif
|
||||||
|
|
||||||
this.addWidget(this.list); // Add the tint to the things to be rendered
|
this.addWidget(this.list); // Add the tint to the things to be rendered
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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)
|
public void render(PoseStack matrices, int mouseX, int mouseY, float delta)
|
||||||
#else
|
#else
|
||||||
public void render(GuiGraphics matrices, int mouseX, int mouseY, float delta)
|
public void render(GuiGraphics matrices, int mouseX, int mouseY, float delta)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
#if MC_1_20_2
|
#if MC_VER < MC_1_20_2
|
||||||
this.renderBackground(matrices, mouseX, mouseY, delta); // Render background
|
|
||||||
#else
|
|
||||||
this.renderBackground(matrices); // Render background
|
this.renderBackground(matrices); // Render background
|
||||||
|
#else
|
||||||
|
this.renderBackground(matrices, mouseX, mouseY, delta); // Render background
|
||||||
#endif
|
#endif
|
||||||
this.list.render(matrices, mouseX, mouseY, delta); // Renders the items in the render list (currently only used to tint background darker)
|
this.list.render(matrices, mouseX, mouseY, delta); // Renders the items in the render list (currently only used to tint background darker)
|
||||||
|
|
||||||
@@ -131,9 +135,13 @@ public class MinecraftScreen
|
|||||||
|
|
||||||
public static class ConfigListWidget extends ContainerObjectSelectionList
|
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;
|
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.network.chat.Component;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
|
||||||
#if POST_MC_1_17_1
|
#if MC_VER >= MC_1_17_1
|
||||||
import net.minecraft.client.renderer.GameRenderer;
|
import net.minecraft.client.renderer.GameRenderer;
|
||||||
#endif
|
#endif
|
||||||
#if PRE_MC_1_20_1
|
#if MC_VER < MC_1_20_1
|
||||||
import com.mojang.blaze3d.vertex.PoseStack;
|
import com.mojang.blaze3d.vertex.PoseStack;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
#else
|
#else
|
||||||
import net.minecraft.client.gui.GuiGraphics;
|
import net.minecraft.client.gui.GuiGraphics;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if PRE_MC_1_20_2
|
#if MC_VER < MC_1_20_2
|
||||||
public class TexturedButtonWidget extends ImageButton
|
public class TexturedButtonWidget extends ImageButton
|
||||||
#else
|
#else
|
||||||
public class TexturedButtonWidget extends Button
|
public class TexturedButtonWidget extends Button
|
||||||
@@ -52,7 +52,7 @@ public class TexturedButtonWidget extends Button
|
|||||||
{
|
{
|
||||||
public final boolean renderBackground;
|
public final boolean renderBackground;
|
||||||
|
|
||||||
#if POST_MC_1_20_2
|
#if MC_VER >= MC_1_20_2
|
||||||
private final int u;
|
private final int u;
|
||||||
private final int v;
|
private final int v;
|
||||||
private final int hoveredVOffset;
|
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)
|
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);
|
super(x, y, width, height, u, v, hoveredVOffset, texture, textureWidth, textureHeight, pressAction, text);
|
||||||
#else
|
#else
|
||||||
// We don't pass on the text option as otherwise it will render (we normally pass it for narration)
|
// 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;
|
this.renderBackground = renderBackground;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if PRE_MC_1_20_2
|
#if MC_VER < MC_1_20_2
|
||||||
#if PRE_MC_1_19_4
|
#if MC_VER < MC_1_19_4
|
||||||
@Override
|
@Override
|
||||||
public void renderButton(PoseStack matrices, int mouseX, int mouseY, float delta) {
|
public void renderButton(PoseStack matrices, int mouseX, int mouseY, float delta) {
|
||||||
if (this.renderBackground) // Renders the background of the button
|
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);
|
Minecraft.getInstance().getTextureManager().bind(WIDGETS_LOCATION);
|
||||||
RenderSystem.color4f(1.0F, 1.0F, 1.0F, this.alpha);
|
RenderSystem.color4f(1.0F, 1.0F, 1.0F, this.alpha);
|
||||||
#else
|
#else
|
||||||
@@ -108,7 +108,7 @@ public class TexturedButtonWidget extends Button
|
|||||||
RenderSystem.enableBlend();
|
RenderSystem.enableBlend();
|
||||||
RenderSystem.defaultBlendFunc();
|
RenderSystem.defaultBlendFunc();
|
||||||
RenderSystem.enableDepthTest();
|
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.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);
|
this.blit(matrices, this.x + this.width / 2, this.y, 200 - this.width / 2, 46 + i * 20, this.width / 2, this.height);
|
||||||
#else
|
#else
|
||||||
@@ -120,7 +120,7 @@ public class TexturedButtonWidget extends Button
|
|||||||
super.renderButton(matrices, mouseX, mouseY, delta);
|
super.renderButton(matrices, mouseX, mouseY, delta);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
#if PRE_MC_1_20_1
|
#if MC_VER < MC_1_20_1
|
||||||
@Override
|
@Override
|
||||||
public void renderWidget(PoseStack matrices, int mouseX, int mouseY, float delta)
|
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;
|
if (!this.active) i = 0;
|
||||||
else if (this.isHovered) i = 2;
|
else if (this.isHovered) i = 2;
|
||||||
|
|
||||||
#if PRE_MC_1_20_1
|
#if MC_VER < MC_1_20_1
|
||||||
RenderSystem.enableBlend();
|
RenderSystem.enableBlend();
|
||||||
RenderSystem.defaultBlendFunc();
|
RenderSystem.defaultBlendFunc();
|
||||||
RenderSystem.enableDepthTest();
|
RenderSystem.enableDepthTest();
|
||||||
|
|||||||
+28
-21
@@ -15,11 +15,11 @@ import net.minecraft.client.gui.components.events.GuiEventListener;
|
|||||||
import net.minecraft.client.gui.screens.Screen;
|
import net.minecraft.client.gui.screens.Screen;
|
||||||
import net.minecraft.network.chat.Component;
|
import net.minecraft.network.chat.Component;
|
||||||
|
|
||||||
#if POST_MC_1_17_1
|
#if MC_VER >= MC_1_17_1
|
||||||
import net.minecraft.client.gui.narration.NarratableEntry;
|
import net.minecraft.client.gui.narration.NarratableEntry;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if PRE_MC_1_20_1
|
#if MC_VER < MC_1_20_1
|
||||||
import net.minecraft.client.gui.GuiComponent;
|
import net.minecraft.client.gui.GuiComponent;
|
||||||
#else
|
#else
|
||||||
import net.minecraft.client.gui.GuiGraphics;
|
import net.minecraft.client.gui.GuiGraphics;
|
||||||
@@ -101,11 +101,17 @@ public class ChangelogScreen extends DhScreen
|
|||||||
this.changelog.add("");
|
this.changelog.add("");
|
||||||
this.changelog.add("");
|
this.changelog.add("");
|
||||||
|
|
||||||
|
String changelog = ModrinthGetter.changeLogs.get(versionID);
|
||||||
|
if (changelog == null)
|
||||||
|
{
|
||||||
|
// in case something goes wrong this will prevent null pointers
|
||||||
|
changelog = "";
|
||||||
|
}
|
||||||
|
|
||||||
// Get the release changelog and split it by the new lines
|
// Get the release changelog and split it by the new lines
|
||||||
String[] unwrappedChangelog = // Arrays.asList could be used if a list object is desired here vs List.of which is only available for Java 9+
|
String[] unwrappedChangelog = // Arrays.asList could be used if a list object is desired here vs List.of which is only available for Java 9+
|
||||||
new MarkdownFormatter.MinecraftFormat().convertTo( // This formats markdown to minecraft's "§" characters
|
// This formats markdown to minecraft's "§" charactersnew MarkdownFormatter.MinecraftFormat().convertTo(
|
||||||
ModrinthGetter.changeLogs.get(versionID)
|
new MarkdownFormatter.MinecraftFormat().convertTo(changelog).split("\\n");
|
||||||
).split("\\n");
|
|
||||||
// Makes the words wrap around to not go off the screen
|
// Makes the words wrap around to not go off the screen
|
||||||
for (String str : unwrappedChangelog)
|
for (String str : unwrappedChangelog)
|
||||||
{
|
{
|
||||||
@@ -128,13 +134,11 @@ public class ChangelogScreen extends DhScreen
|
|||||||
|
|
||||||
|
|
||||||
this.addBtn( // Close
|
this.addBtn( // Close
|
||||||
MakeBtn(Translatable(ModInfo.ID + ".general.back"), 5, this.height - 25, 100, 20, (btn) -> {
|
MakeBtn(Translatable(ModInfo.ID + ".general.back"), 5, this.height - 25, 100, 20, (btn) -> this.onClose())
|
||||||
this.onClose();
|
|
||||||
})
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
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++)
|
for (int i = 0; i < changelog.size(); i++)
|
||||||
{
|
{
|
||||||
this.changelogArea.addButton(TextOrLiteral(changelog.get(i)));
|
this.changelogArea.addButton(TextOrLiteral(changelog.get(i)));
|
||||||
@@ -144,16 +148,16 @@ public class ChangelogScreen extends DhScreen
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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)
|
public void render(PoseStack matrices, int mouseX, int mouseY, float delta)
|
||||||
#else
|
#else
|
||||||
public void render(GuiGraphics matrices, int mouseX, int mouseY, float delta)
|
public void render(GuiGraphics matrices, int mouseX, int mouseY, float delta)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
#if MC_1_20_2
|
#if MC_VER < MC_1_20_2
|
||||||
this.renderBackground(matrices, mouseX, mouseY, delta); // Render background
|
|
||||||
#else
|
|
||||||
this.renderBackground(matrices); // Render background
|
this.renderBackground(matrices); // Render background
|
||||||
|
#else
|
||||||
|
this.renderBackground(matrices, mouseX, mouseY, delta); // Render background
|
||||||
#endif
|
#endif
|
||||||
if (!usable)
|
if (!usable)
|
||||||
return;
|
return;
|
||||||
@@ -161,17 +165,16 @@ public class ChangelogScreen extends DhScreen
|
|||||||
// Set the scroll position to the mouse height relative to the screen
|
// 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
|
// 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();
|
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);
|
this.changelogArea.setScrollAmount(scrollAmount);
|
||||||
#else
|
#else
|
||||||
this.changelogArea.scrollAmount = scrollAmount;
|
this.changelogArea.scrollAmount = scrollAmount;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
this.changelogArea.render(matrices, mouseX, mouseY, delta); // Render the changelog
|
// render order matters, otherwise on 1.20.6+ the blurred background will render on top of the text
|
||||||
|
|
||||||
super.render(matrices, mouseX, mouseY, delta); // Render the buttons
|
super.render(matrices, mouseX, mouseY, delta); // Render the buttons
|
||||||
|
this.changelogArea.render(matrices, mouseX, mouseY, delta); // Render the changelog
|
||||||
DhDrawCenteredString(matrices, font, title, width / 2, 15, 0xFFFFFF); // Render title
|
DhDrawCenteredString(matrices, font, title, width / 2, 15, 0xFFFFFF); // Render title
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -185,9 +188,13 @@ public class ChangelogScreen extends DhScreen
|
|||||||
{
|
{
|
||||||
Font textRenderer;
|
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;
|
this.centerListVertically = false;
|
||||||
textRenderer = minecraftClient.font;
|
textRenderer = minecraftClient.font;
|
||||||
}
|
}
|
||||||
@@ -221,7 +228,7 @@ public class ChangelogScreen extends DhScreen
|
|||||||
return new ButtonEntry(text);
|
return new ButtonEntry(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if PRE_MC_1_20_1
|
#if MC_VER < MC_1_20_1
|
||||||
@Override
|
@Override
|
||||||
public void render(PoseStack matrices, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean hovered, float tickDelta)
|
public void render(PoseStack matrices, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean hovered, float tickDelta)
|
||||||
{
|
{
|
||||||
@@ -240,7 +247,7 @@ public class ChangelogScreen extends DhScreen
|
|||||||
{
|
{
|
||||||
return children;
|
return children;
|
||||||
}
|
}
|
||||||
#if POST_MC_1_17_1
|
#if MC_VER >= MC_1_17_1
|
||||||
@Override
|
@Override
|
||||||
public List<? extends NarratableEntry> narratables()
|
public List<? extends NarratableEntry> narratables()
|
||||||
{
|
{
|
||||||
|
|||||||
+36
-37
@@ -1,23 +1,19 @@
|
|||||||
package com.seibel.distanthorizons.common.wrappers.gui.updater;
|
package com.seibel.distanthorizons.common.wrappers.gui.updater;
|
||||||
|
|
||||||
import com.mojang.blaze3d.platform.NativeImage;
|
import com.seibel.distanthorizons.api.enums.config.EDhApiUpdateBranch;
|
||||||
import com.seibel.distanthorizons.api.enums.config.EUpdateBranch;
|
|
||||||
import com.seibel.distanthorizons.common.wrappers.gui.DhScreen;
|
import com.seibel.distanthorizons.common.wrappers.gui.DhScreen;
|
||||||
import com.seibel.distanthorizons.common.wrappers.gui.TexturedButtonWidget;
|
import com.seibel.distanthorizons.common.wrappers.gui.TexturedButtonWidget;
|
||||||
import com.seibel.distanthorizons.core.jar.ModJarInfo;
|
import com.seibel.distanthorizons.core.jar.ModJarInfo;
|
||||||
import com.seibel.distanthorizons.coreapi.ModInfo;
|
import com.seibel.distanthorizons.coreapi.ModInfo;
|
||||||
import com.seibel.distanthorizons.core.config.Config;
|
import com.seibel.distanthorizons.core.config.Config;
|
||||||
import com.seibel.distanthorizons.core.jar.JarUtils;
|
|
||||||
import com.seibel.distanthorizons.core.jar.installer.ModrinthGetter;
|
import com.seibel.distanthorizons.core.jar.installer.ModrinthGetter;
|
||||||
import com.seibel.distanthorizons.core.jar.updater.SelfUpdater;
|
import com.seibel.distanthorizons.core.jar.updater.SelfUpdater;
|
||||||
import net.minecraft.client.Minecraft;
|
#if MC_VER >= MC_1_20_1
|
||||||
#if POST_MC_1_20_1
|
|
||||||
import net.minecraft.client.gui.GuiGraphics;
|
import net.minecraft.client.gui.GuiGraphics;
|
||||||
#else
|
#else
|
||||||
import com.mojang.blaze3d.vertex.PoseStack;
|
import com.mojang.blaze3d.vertex.PoseStack;
|
||||||
#endif
|
#endif
|
||||||
import net.minecraft.client.gui.screens.Screen;
|
import net.minecraft.client.gui.screens.Screen;
|
||||||
import net.minecraft.client.renderer.texture.DynamicTexture;
|
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
|
||||||
import static com.seibel.distanthorizons.common.wrappers.gui.GuiHelper.*;
|
import static com.seibel.distanthorizons.common.wrappers.gui.GuiHelper.*;
|
||||||
@@ -46,15 +42,17 @@ public class UpdateModScreen extends DhScreen
|
|||||||
this.parent = parent;
|
this.parent = parent;
|
||||||
this.newVersionID = newVersionID;
|
this.newVersionID = newVersionID;
|
||||||
|
|
||||||
switch (Config.Client.Advanced.AutoUpdater.updateBranch.get()) {
|
|
||||||
case STABLE:
|
EDhApiUpdateBranch updateBranch = EDhApiUpdateBranch.convertAutoToStableOrNightly(Config.Client.Advanced.AutoUpdater.updateBranch.get());
|
||||||
currentVer = ModInfo.VERSION;
|
if (updateBranch == EDhApiUpdateBranch.STABLE)
|
||||||
nextVer = ModrinthGetter.releaseNames.get(this.newVersionID);
|
{
|
||||||
break;
|
this.currentVer = ModInfo.VERSION;
|
||||||
case NIGHTLY:
|
this.nextVer = ModrinthGetter.releaseNames.get(this.newVersionID);
|
||||||
currentVer = ModJarInfo.Git_Commit.substring(0,7);
|
}
|
||||||
nextVer = this.newVersionID.substring(0,7);
|
else
|
||||||
break;
|
{
|
||||||
|
this.currentVer = ModJarInfo.Git_Commit.substring(0,7);
|
||||||
|
this.nextVer = this.newVersionID.substring(0,7);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -66,13 +64,6 @@ public class UpdateModScreen extends DhScreen
|
|||||||
|
|
||||||
try
|
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
|
// Logo image
|
||||||
@@ -84,7 +75,13 @@ public class UpdateModScreen extends DhScreen
|
|||||||
// Offset
|
// Offset
|
||||||
0, 0,
|
0, 0,
|
||||||
// Some textuary stuff
|
// Some textuary stuff
|
||||||
0, logoLocation, 130, 65,
|
0,
|
||||||
|
#if MC_VER < MC_1_21
|
||||||
|
new ResourceLocation(ModInfo.ID, "logo.png"),
|
||||||
|
#else
|
||||||
|
ResourceLocation.fromNamespaceAndPath(ModInfo.ID, "logo.png"),
|
||||||
|
#endif
|
||||||
|
130, 65,
|
||||||
// Create the button and tell it where to go
|
// Create the button and tell it where to go
|
||||||
// For now it goes to the client option by default
|
// 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)
|
(buttonWidget) -> System.out.println("Nice, you found an easter egg :)"), // TODO: Add a proper easter egg to pressing the logo (maybe with confetti)
|
||||||
@@ -99,7 +96,7 @@ public class UpdateModScreen extends DhScreen
|
|||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Config.Client.Advanced.AutoUpdater.updateBranch.get() == EUpdateBranch.STABLE)
|
if (!ModInfo.IS_DEV_BUILD)
|
||||||
{
|
{
|
||||||
this.addBtn(new TexturedButtonWidget(
|
this.addBtn(new TexturedButtonWidget(
|
||||||
// Where the button is on the screen
|
// Where the button is on the screen
|
||||||
@@ -109,7 +106,13 @@ public class UpdateModScreen extends DhScreen
|
|||||||
// Offset
|
// Offset
|
||||||
0, 0,
|
0, 0,
|
||||||
// Some textuary stuff
|
// Some textuary stuff
|
||||||
0, new ResourceLocation(ModInfo.ID, "textures/gui/changelog.png"), 20, 20,
|
0,
|
||||||
|
#if MC_VER < MC_1_21
|
||||||
|
new ResourceLocation(ModInfo.ID, "textures/gui/changelog.png"),
|
||||||
|
#else
|
||||||
|
ResourceLocation.fromNamespaceAndPath(ModInfo.ID, "textures/gui/changelog.png"),
|
||||||
|
#endif
|
||||||
|
20, 20,
|
||||||
// Create the button and tell it where to go
|
// Create the button and tell it where to go
|
||||||
(buttonWidget) -> Objects.requireNonNull(minecraft).setScreen(new ChangelogScreen(this, this.newVersionID)), // TODO: Add a proper easter egg to pressing the logo (maybe with confetti)
|
(buttonWidget) -> Objects.requireNonNull(minecraft).setScreen(new ChangelogScreen(this, this.newVersionID)), // TODO: Add a proper easter egg to pressing the logo (maybe with confetti)
|
||||||
// Add a title to the button
|
// Add a title to the button
|
||||||
@@ -132,9 +135,7 @@ public class UpdateModScreen extends DhScreen
|
|||||||
})
|
})
|
||||||
);
|
);
|
||||||
this.addBtn( // Later (not now)
|
this.addBtn( // Later (not now)
|
||||||
MakeBtn(Translatable(ModInfo.ID + ".updater.later"), this.width / 2 + 2, this.height / 2 + 70, 100, 20, (btn) -> {
|
MakeBtn(Translatable(ModInfo.ID + ".updater.later"), this.width / 2 + 2, this.height / 2 + 70, 100, 20, (btn) -> this.onClose())
|
||||||
this.onClose();
|
|
||||||
})
|
|
||||||
);
|
);
|
||||||
this.addBtn( // Never
|
this.addBtn( // Never
|
||||||
MakeBtn(Translatable(ModInfo.ID + ".updater.never"), this.width / 2 - 102, this.height / 2 + 70, 100, 20, (btn) -> {
|
MakeBtn(Translatable(ModInfo.ID + ".updater.never"), this.width / 2 - 102, this.height / 2 + 70, 100, 20, (btn) -> {
|
||||||
@@ -146,29 +147,27 @@ public class UpdateModScreen extends DhScreen
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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)
|
public void render(PoseStack matrices, int mouseX, int mouseY, float delta)
|
||||||
#else
|
#else
|
||||||
public void render(GuiGraphics matrices, int mouseX, int mouseY, float delta)
|
public void render(GuiGraphics matrices, int mouseX, int mouseY, float delta)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
#if MC_1_20_2
|
#if MC_VER < MC_1_20_2
|
||||||
this.renderBackground(matrices, mouseX, mouseY, delta); // Render background
|
|
||||||
#else
|
|
||||||
this.renderBackground(matrices); // Render background
|
this.renderBackground(matrices); // Render background
|
||||||
|
#else
|
||||||
|
this.renderBackground(matrices, mouseX, mouseY, delta); // Render background
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// TODO: add the tooltips for the buttons
|
||||||
|
super.render(matrices, mouseX, mouseY, delta); // Render the buttons
|
||||||
|
// TODO: Add tooltips
|
||||||
|
|
||||||
// Render the text's
|
// Render the text's
|
||||||
DhDrawCenteredString(matrices, this.font, Translatable(ModInfo.ID + ".updater.text1"), this.width / 2, this.height / 2 - 35, 0xFFFFFF);
|
DhDrawCenteredString(matrices, this.font, Translatable(ModInfo.ID + ".updater.text1"), this.width / 2, this.height / 2 - 35, 0xFFFFFF);
|
||||||
DhDrawCenteredString(matrices, this.font,
|
DhDrawCenteredString(matrices, this.font,
|
||||||
Translatable(ModInfo.ID + ".updater.text2", currentVer, nextVer),
|
Translatable(ModInfo.ID + ".updater.text2", currentVer, nextVer),
|
||||||
this.width / 2, this.height / 2 - 20, 0x52FD52);
|
this.width / 2, this.height / 2 - 20, 0x52FD52);
|
||||||
|
|
||||||
// TODO: add the tooltips for the buttons
|
|
||||||
super.render(matrices, mouseX, mouseY, delta); // Render the buttons
|
|
||||||
|
|
||||||
// TODO: Add tooltips
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
+88
-95
@@ -25,12 +25,13 @@ import java.util.ArrayList;
|
|||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import com.mojang.blaze3d.platform.NativeImage;
|
import com.mojang.blaze3d.platform.NativeImage;
|
||||||
import com.seibel.distanthorizons.api.enums.config.ELodShading;
|
import com.seibel.distanthorizons.api.enums.config.EDhApiLodShading;
|
||||||
import com.seibel.distanthorizons.common.wrappers.McObjectConverter;
|
import com.seibel.distanthorizons.common.wrappers.McObjectConverter;
|
||||||
import com.seibel.distanthorizons.common.wrappers.world.ClientLevelWrapper;
|
import com.seibel.distanthorizons.common.wrappers.world.ClientLevelWrapper;
|
||||||
import com.seibel.distanthorizons.common.wrappers.world.ServerLevelWrapper;
|
import com.seibel.distanthorizons.common.wrappers.world.ServerLevelWrapper;
|
||||||
import com.seibel.distanthorizons.core.config.Config;
|
import com.seibel.distanthorizons.core.config.Config;
|
||||||
import com.seibel.distanthorizons.core.enums.EDhDirection;
|
import com.seibel.distanthorizons.core.enums.EDhDirection;
|
||||||
|
import com.seibel.distanthorizons.core.file.structure.ClientOnlySaveStructure;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
|
||||||
import com.seibel.distanthorizons.coreapi.ModInfo;
|
import com.seibel.distanthorizons.coreapi.ModInfo;
|
||||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||||
@@ -43,11 +44,12 @@ import com.seibel.distanthorizons.core.pos.DhChunkPos;
|
|||||||
|
|
||||||
import net.minecraft.CrashReport;
|
import net.minecraft.CrashReport;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.client.multiplayer.ServerData;
|
||||||
import net.minecraft.client.player.LocalPlayer;
|
import net.minecraft.client.player.LocalPlayer;
|
||||||
import net.minecraft.client.resources.model.ModelManager;
|
import net.minecraft.client.resources.model.ModelManager;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.core.Direction;
|
import net.minecraft.core.Direction;
|
||||||
#if PRE_MC_1_19_2
|
#if MC_VER < MC_1_19_2
|
||||||
import net.minecraft.network.chat.TextComponent;
|
import net.minecraft.network.chat.TextComponent;
|
||||||
#endif
|
#endif
|
||||||
import net.minecraft.server.level.ServerLevel;
|
import net.minecraft.server.level.ServerLevel;
|
||||||
@@ -59,16 +61,15 @@ import org.jetbrains.annotations.Nullable;
|
|||||||
* A singleton that wraps the Minecraft object.
|
* A singleton that wraps the Minecraft object.
|
||||||
*
|
*
|
||||||
* @author James Seibel
|
* @author James Seibel
|
||||||
* @version 3-5-2022
|
|
||||||
*/
|
*/
|
||||||
//@Environment(EnvType.CLIENT)
|
|
||||||
public class MinecraftClientWrapper implements IMinecraftClientWrapper, IMinecraftSharedWrapper
|
public class MinecraftClientWrapper implements IMinecraftClientWrapper, IMinecraftSharedWrapper
|
||||||
{
|
{
|
||||||
private static final Logger LOGGER = DhLoggerBuilder.getLogger(MethodHandles.lookup().lookupClass().getSimpleName());
|
private static final Logger LOGGER = DhLoggerBuilder.getLogger(MethodHandles.lookup().lookupClass().getSimpleName());
|
||||||
|
private static final Minecraft MINECRAFT = Minecraft.getInstance();
|
||||||
|
|
||||||
public static final MinecraftClientWrapper INSTANCE = new MinecraftClientWrapper();
|
public static final MinecraftClientWrapper INSTANCE = new MinecraftClientWrapper();
|
||||||
|
|
||||||
public final Minecraft mc = Minecraft.getInstance();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The lightmap for the current:
|
* The lightmap for the current:
|
||||||
@@ -99,10 +100,7 @@ public class MinecraftClientWrapper implements IMinecraftClientWrapper, IMinecra
|
|||||||
* This doesn't affect OpenGL objects in any way.
|
* This doesn't affect OpenGL objects in any way.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void clearFrameObjectCache()
|
public void clearFrameObjectCache() { this.lightMap = null; }
|
||||||
{
|
|
||||||
lightMap = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -113,140 +111,140 @@ public class MinecraftClientWrapper implements IMinecraftClientWrapper, IMinecra
|
|||||||
@Override
|
@Override
|
||||||
public float getShade(EDhDirection lodDirection)
|
public float getShade(EDhDirection lodDirection)
|
||||||
{
|
{
|
||||||
ELodShading lodShading = Config.Client.Advanced.Graphics.AdvancedGraphics.lodShading.get();
|
EDhApiLodShading lodShading = Config.Client.Advanced.Graphics.AdvancedGraphics.lodShading.get();
|
||||||
switch (lodShading)
|
switch (lodShading)
|
||||||
{
|
{
|
||||||
default:
|
default:
|
||||||
case MINECRAFT:
|
case AUTO:
|
||||||
if (this.mc.level != null)
|
if (MINECRAFT.level != null)
|
||||||
{
|
{
|
||||||
Direction mcDir = McObjectConverter.Convert(lodDirection);
|
Direction mcDir = McObjectConverter.Convert(lodDirection);
|
||||||
return this.mc.level.getShade(mcDir, true);
|
return MINECRAFT.level.getShade(mcDir, true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return 0.0f;
|
return 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
case OLD_LIGHTING:
|
case ENABLED:
|
||||||
switch (lodDirection)
|
return switch (lodDirection) {
|
||||||
|
case DOWN -> 0.5F;
|
||||||
|
default -> 1.0F;
|
||||||
|
case NORTH, SOUTH -> 0.8F;
|
||||||
|
case WEST, EAST -> 0.6F;
|
||||||
|
};
|
||||||
|
|
||||||
|
case DISABLED:
|
||||||
|
return 1.0F;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasSinglePlayerServer() { return MINECRAFT.hasSingleplayerServer(); }
|
||||||
|
@Override
|
||||||
|
public boolean clientConnectedToDedicatedServer() { return MINECRAFT.getCurrentServer() != null && !this.hasSinglePlayerServer(); }
|
||||||
|
@Override
|
||||||
|
public boolean connectedToReplay() { return !MINECRAFT.hasSingleplayerServer() && MINECRAFT.getCurrentServer() == null; }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getCurrentServerName()
|
||||||
{
|
{
|
||||||
case DOWN:
|
if (this.connectedToReplay())
|
||||||
return 0.5F;
|
{
|
||||||
default:
|
return ClientOnlySaveStructure.REPLAY_SERVER_FOLDER_NAME;
|
||||||
case UP:
|
|
||||||
return 1.0F;
|
|
||||||
case NORTH:
|
|
||||||
case SOUTH:
|
|
||||||
return 0.8F;
|
|
||||||
case WEST:
|
|
||||||
case EAST:
|
|
||||||
return 0.6F;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
case NONE:
|
{
|
||||||
return 1.0F;
|
ServerData server = MINECRAFT.getCurrentServer();
|
||||||
|
return (server != null) ? server.name : "NULL";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasSinglePlayerServer() { return mc.hasSingleplayerServer(); }
|
public String getCurrentServerIp()
|
||||||
@Override
|
{
|
||||||
public boolean clientConnectedToDedicatedServer() { return mc.getCurrentServer() != null && !this.hasSinglePlayerServer(); }
|
if (this.connectedToReplay())
|
||||||
|
{
|
||||||
@Override
|
return "";
|
||||||
public String getCurrentServerName() { return mc.getCurrentServer().name; }
|
}
|
||||||
|
else
|
||||||
@Override
|
{
|
||||||
public String getCurrentServerIp() { return mc.getCurrentServer().ip; }
|
ServerData server = MINECRAFT.getCurrentServer();
|
||||||
|
return (server != null) ? server.ip : "NA";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getCurrentServerVersion()
|
public String getCurrentServerVersion()
|
||||||
{
|
{
|
||||||
return mc.getCurrentServer().version.getString();
|
ServerData server = MINECRAFT.getCurrentServer();
|
||||||
|
return (server != null) ? server.version.getString() : "UNKOWN";
|
||||||
}
|
}
|
||||||
|
|
||||||
//=============//
|
//=============//
|
||||||
// Simple gets //
|
// Simple gets //
|
||||||
//=============//
|
//=============//
|
||||||
|
|
||||||
public LocalPlayer getPlayer()
|
public LocalPlayer getPlayer() { return MINECRAFT.player; }
|
||||||
{
|
|
||||||
return mc.player;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean playerExists()
|
public boolean playerExists() { return MINECRAFT.player != null; }
|
||||||
{
|
|
||||||
return mc.player != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UUID getPlayerUUID()
|
public UUID getPlayerUUID() { return this.getPlayer().getUUID(); }
|
||||||
{
|
|
||||||
return getPlayer().getUUID();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DhBlockPos getPlayerBlockPos()
|
public DhBlockPos getPlayerBlockPos()
|
||||||
{
|
{
|
||||||
BlockPos playerPos = getPlayer().blockPosition();
|
BlockPos playerPos = this.getPlayer().blockPosition();
|
||||||
return new DhBlockPos(playerPos.getX(), playerPos.getY(), playerPos.getZ());
|
return new DhBlockPos(playerPos.getX(), playerPos.getY(), playerPos.getZ());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DhChunkPos getPlayerChunkPos()
|
public DhChunkPos getPlayerChunkPos()
|
||||||
{
|
{
|
||||||
#if PRE_MC_1_17_1
|
#if MC_VER < MC_1_17_1
|
||||||
ChunkPos playerPos = new ChunkPos(getPlayer().blockPosition());
|
ChunkPos playerPos = new ChunkPos(this.getPlayer().blockPosition());
|
||||||
#else
|
#else
|
||||||
ChunkPos playerPos = getPlayer().chunkPosition();
|
ChunkPos playerPos = this.getPlayer().chunkPosition();
|
||||||
#endif
|
#endif
|
||||||
return new DhChunkPos(playerPos.x, playerPos.z);
|
return new DhChunkPos(playerPos.x, playerPos.z);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ModelManager getModelManager()
|
|
||||||
{
|
|
||||||
return mc.getModelManager();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public IClientLevelWrapper getWrappedClientLevel()
|
public IClientLevelWrapper getWrappedClientLevel()
|
||||||
{
|
{
|
||||||
if (this.mc.level == null)
|
if (MINECRAFT.level == null)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ClientLevelWrapper.getWrapperIgnoringOverride(this.mc.level);
|
return ClientLevelWrapper.getWrapperIgnoringOverride(MINECRAFT.level);
|
||||||
}
|
|
||||||
|
|
||||||
/** Please move over to getInstallationDirectory() */
|
|
||||||
@Deprecated
|
|
||||||
@Override
|
|
||||||
public File getGameDirectory()
|
|
||||||
{
|
|
||||||
return getInstallationDirectory();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IProfilerWrapper getProfiler()
|
public IProfilerWrapper getProfiler()
|
||||||
{
|
{
|
||||||
if (profilerWrapper == null)
|
if (this.profilerWrapper == null)
|
||||||
profilerWrapper = new ProfilerWrapper(mc.getProfiler());
|
{
|
||||||
else if (mc.getProfiler() != profilerWrapper.profiler)
|
this.profilerWrapper = new ProfilerWrapper(MINECRAFT.getProfiler());
|
||||||
profilerWrapper.profiler = mc.getProfiler();
|
}
|
||||||
return profilerWrapper;
|
else if (MINECRAFT.getProfiler() != this.profilerWrapper.profiler)
|
||||||
|
{
|
||||||
|
this.profilerWrapper.profiler = MINECRAFT.getProfiler();
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.profilerWrapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns all worlds available to the server */
|
/** Returns all worlds available to the server */
|
||||||
@Override
|
@Override
|
||||||
public ArrayList<ILevelWrapper> getAllServerWorlds()
|
public ArrayList<ILevelWrapper> getAllServerWorlds()
|
||||||
{
|
{
|
||||||
ArrayList<ILevelWrapper> worlds = new ArrayList<ILevelWrapper>();
|
ArrayList<ILevelWrapper> worlds = new ArrayList<>();
|
||||||
|
|
||||||
Iterable<ServerLevel> serverWorlds = mc.getSingleplayerServer().getAllLevels();
|
Iterable<ServerLevel> serverWorlds = MINECRAFT.getSingleplayerServer().getAllLevels();
|
||||||
for (ServerLevel world : serverWorlds)
|
for (ServerLevel world : serverWorlds)
|
||||||
{
|
{
|
||||||
worlds.add(ServerLevelWrapper.getWrapper(world));
|
worlds.add(ServerLevelWrapper.getWrapper(world));
|
||||||
@@ -260,12 +258,12 @@ public class MinecraftClientWrapper implements IMinecraftClientWrapper, IMinecra
|
|||||||
@Override
|
@Override
|
||||||
public void sendChatMessage(String string)
|
public void sendChatMessage(String string)
|
||||||
{
|
{
|
||||||
LocalPlayer p = getPlayer();
|
LocalPlayer player = this.getPlayer();
|
||||||
if (p == null) return;
|
if (player == null) return;
|
||||||
#if PRE_MC_1_19_2
|
#if MC_VER < MC_1_19_2
|
||||||
p.sendMessage(new TextComponent(string), getPlayer().getUUID());
|
player.sendMessage(new TextComponent(string), getPlayer().getUUID());
|
||||||
#else
|
#else
|
||||||
p.sendSystemMessage(net.minecraft.network.chat.Component.translatable(string));
|
player.sendSystemMessage(net.minecraft.network.chat.Component.translatable(string));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -282,28 +280,23 @@ public class MinecraftClientWrapper implements IMinecraftClientWrapper, IMinecra
|
|||||||
{
|
{
|
||||||
LOGGER.error(ModInfo.READABLE_NAME + " had the following error: [" + errorMessage + "]. Crashing Minecraft...", exception);
|
LOGGER.error(ModInfo.READABLE_NAME + " had the following error: [" + errorMessage + "]. Crashing Minecraft...", exception);
|
||||||
CrashReport report = new CrashReport(errorMessage, exception);
|
CrashReport report = new CrashReport(errorMessage, exception);
|
||||||
|
#if MC_VER < MC_1_20_4
|
||||||
Minecraft.crash(report);
|
Minecraft.crash(report);
|
||||||
|
#else
|
||||||
|
Minecraft.getInstance().delayCrash(report);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object getOptionsObject()
|
public Object getOptionsObject() { return MINECRAFT.options; }
|
||||||
{
|
|
||||||
return mc.options;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isDedicatedServer()
|
public boolean isDedicatedServer() { return false; }
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public File getInstallationDirectory()
|
public File getInstallationDirectory() { return MINECRAFT.gameDirectory; }
|
||||||
{
|
|
||||||
return mc.gameDirectory;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void executeOnRenderThread(Runnable runnable) { this.mc.execute(runnable); }
|
public void executeOnRenderThread(Runnable runnable) { MINECRAFT.execute(runnable); }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+10
-6
@@ -12,16 +12,20 @@ public class MinecraftDedicatedServerWrapper implements IMinecraftSharedWrapper
|
|||||||
private MinecraftDedicatedServerWrapper() { }
|
private MinecraftDedicatedServerWrapper() { }
|
||||||
public DedicatedServer dedicatedServer = null;
|
public DedicatedServer dedicatedServer = null;
|
||||||
@Override
|
@Override
|
||||||
public boolean isDedicatedServer()
|
public boolean isDedicatedServer() { return true; }
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
@Override
|
@Override
|
||||||
public File getInstallationDirectory()
|
public File getInstallationDirectory()
|
||||||
{
|
{
|
||||||
if (dedicatedServer == null)
|
if (this.dedicatedServer == null)
|
||||||
|
{
|
||||||
throw new IllegalStateException("Trying to get Installation Direction before Dedicated server complete initialization!");
|
throw new IllegalStateException("Trying to get Installation Direction before Dedicated server complete initialization!");
|
||||||
return dedicatedServer.getServerDirectory();
|
}
|
||||||
|
|
||||||
|
#if MC_VER < MC_1_21
|
||||||
|
return this.dedicatedServer.getServerDirectory();
|
||||||
|
#else
|
||||||
|
return this.dedicatedServer.getServerDirectory().toFile();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+58
-41
@@ -22,8 +22,8 @@ package com.seibel.distanthorizons.common.wrappers.minecraft;
|
|||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
import java.lang.invoke.MethodHandles;
|
import java.lang.invoke.MethodHandles;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import com.mojang.blaze3d.pipeline.RenderTarget;
|
import com.mojang.blaze3d.pipeline.RenderTarget;
|
||||||
@@ -36,15 +36,16 @@ import com.seibel.distanthorizons.core.pos.DhChunkPos;
|
|||||||
import com.seibel.distanthorizons.core.dependencyInjection.ModAccessorInjector;
|
import com.seibel.distanthorizons.core.dependencyInjection.ModAccessorInjector;
|
||||||
|
|
||||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||||
import com.seibel.distanthorizons.core.render.DhApiRenderProxy;
|
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.misc.ILightMapWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.misc.ILightMapWrapper;
|
||||||
|
|
||||||
#if PRE_MC_1_19_4
|
#if MC_VER < MC_1_19_4
|
||||||
import com.mojang.math.Vector3f;
|
import org.joml.Matrix4f;
|
||||||
|
import org.joml.Vector3f;
|
||||||
#else
|
#else
|
||||||
|
import org.joml.Matrix4f;
|
||||||
import org.joml.Vector3f;
|
import org.joml.Vector3f;
|
||||||
#endif
|
#endif
|
||||||
#if MC_1_20_2
|
#if MC_VER >= MC_1_20_2
|
||||||
import net.minecraft.client.renderer.chunk.SectionRenderDispatcher;
|
import net.minecraft.client.renderer.chunk.SectionRenderDispatcher;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -52,9 +53,9 @@ import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.AbstractOpt
|
|||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IDimensionTypeWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IDimensionTypeWrapper;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper;
|
||||||
import com.seibel.distanthorizons.coreapi.util.math.Mat4f;
|
import com.seibel.distanthorizons.core.util.math.Mat4f;
|
||||||
import com.seibel.distanthorizons.coreapi.util.math.Vec3d;
|
import com.seibel.distanthorizons.core.util.math.Vec3d;
|
||||||
import com.seibel.distanthorizons.coreapi.util.math.Vec3f;
|
import com.seibel.distanthorizons.core.util.math.Vec3f;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.IWrapperFactory;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.IWrapperFactory;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IOptifineAccessor;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IOptifineAccessor;
|
||||||
@@ -67,7 +68,7 @@ import net.minecraft.client.renderer.FogRenderer;
|
|||||||
import net.minecraft.client.renderer.LevelRenderer;
|
import net.minecraft.client.renderer.LevelRenderer;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.world.effect.MobEffects;
|
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.tags.FluidTags;
|
||||||
import net.minecraft.world.entity.Entity;
|
import net.minecraft.world.entity.Entity;
|
||||||
import net.minecraft.world.level.material.FluidState;
|
import net.minecraft.world.level.material.FluidState;
|
||||||
@@ -102,7 +103,7 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper
|
|||||||
* In the case of immersive portals multiple levels may be active at once, causing conflicting lightmaps. <br>
|
* In the case of immersive portals multiple levels may be active at once, causing conflicting lightmaps. <br>
|
||||||
* Requiring the use of multiple {@link LightMapWrapper}.
|
* Requiring the use of multiple {@link LightMapWrapper}.
|
||||||
*/
|
*/
|
||||||
public HashMap<IDimensionTypeWrapper, LightMapWrapper> lightmapByDimensionType = new HashMap<>();
|
public ConcurrentHashMap<IDimensionTypeWrapper, LightMapWrapper> lightmapByDimensionType = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds the render buffer that should be used when displaying levels to the screen.
|
* Holds the render buffer that should be used when displaying levels to the screen.
|
||||||
@@ -116,8 +117,7 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper
|
|||||||
public Vec3f getLookAtVector()
|
public Vec3f getLookAtVector()
|
||||||
{
|
{
|
||||||
Camera camera = MC.gameRenderer.getMainCamera();
|
Camera camera = MC.gameRenderer.getMainCamera();
|
||||||
Vector3f cameraDir = camera.getLookVector();
|
return new Vec3f(camera.getLookVector().x(), camera.getLookVector().y(), camera.getLookVector().z());
|
||||||
return new Vec3f(cameraDir.x(), cameraDir.y(), cameraDir.z());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -133,7 +133,7 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper
|
|||||||
public boolean playerHasBlindingEffect()
|
public boolean playerHasBlindingEffect()
|
||||||
{
|
{
|
||||||
return MC.player.getActiveEffectsMap().get(MobEffects.BLINDNESS) != null
|
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
|
|| MC.player.getActiveEffectsMap().get(MobEffects.DARKNESS) != null // Deep dark effect
|
||||||
#endif
|
#endif
|
||||||
;
|
;
|
||||||
@@ -148,10 +148,27 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper
|
|||||||
return new Vec3d(projectedView.x, projectedView.y, projectedView.z);
|
return new Vec3d(projectedView.x, projectedView.y, projectedView.z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Mat4f getWorldViewMatrix()
|
||||||
|
{
|
||||||
|
Camera camera = MC.gameRenderer.getMainCamera();
|
||||||
|
Vector3f cameraVec3 = new Vector3f(
|
||||||
|
(float)camera.getPosition().x,
|
||||||
|
(float)camera.getPosition().y,
|
||||||
|
(float)camera.getPosition().z);
|
||||||
|
cameraVec3 = cameraVec3.negate();
|
||||||
|
|
||||||
|
Matrix4f matWorldView = new Matrix4f()
|
||||||
|
.rotateX((float)Math.toRadians(camera.getXRot()))
|
||||||
|
.rotateY((float)Math.toRadians(camera.getYRot() + 180f))
|
||||||
|
.translate(cameraVec3);
|
||||||
|
return new Mat4f(matWorldView);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Mat4f getDefaultProjectionMatrix(float partialTicks)
|
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));
|
return McObjectConverter.Convert(Minecraft.getInstance().gameRenderer.getProjectionMatrix(Minecraft.getInstance().gameRenderer.getMainCamera(), partialTicks, true));
|
||||||
#else
|
#else
|
||||||
return McObjectConverter.Convert(MC.gameRenderer.getProjectionMatrix(MC.gameRenderer.getFov(MC.gameRenderer.getMainCamera(), partialTicks, true)));
|
return McObjectConverter.Convert(MC.gameRenderer.getProjectionMatrix(MC.gameRenderer.getFov(MC.gameRenderer.getMainCamera(), partialTicks, true)));
|
||||||
@@ -161,7 +178,7 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper
|
|||||||
@Override
|
@Override
|
||||||
public double getGamma()
|
public double getGamma()
|
||||||
{
|
{
|
||||||
#if PRE_MC_1_19_2
|
#if MC_VER < MC_1_19_2
|
||||||
return MC.options.gamma;
|
return MC.options.gamma;
|
||||||
#else
|
#else
|
||||||
return MC.options.gamma().get();
|
return MC.options.gamma().get();
|
||||||
@@ -171,7 +188,7 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper
|
|||||||
@Override
|
@Override
|
||||||
public Color getFogColor(float partialTicks)
|
public Color getFogColor(float partialTicks)
|
||||||
{
|
{
|
||||||
#if PRE_MC_1_17_1
|
#if MC_VER < MC_1_17_1
|
||||||
float[] colorValues = new float[4];
|
float[] colorValues = new float[4];
|
||||||
GL15.glGetFloatv(GL15.GL_FOG_COLOR, colorValues);
|
GL15.glGetFloatv(GL15.GL_FOG_COLOR, colorValues);
|
||||||
#else
|
#else
|
||||||
@@ -192,16 +209,25 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper
|
|||||||
{
|
{
|
||||||
if (MC.level.dimensionType().hasSkyLight())
|
if (MC.level.dimensionType().hasSkyLight())
|
||||||
{
|
{
|
||||||
#if PRE_MC_1_17_1
|
float frameTime;
|
||||||
Vec3 colorValues = MC.level.getSkyColor(MC.gameRenderer.getMainCamera().getBlockPosition(), MC.getFrameTime());
|
#if MC_VER < MC_1_21
|
||||||
|
frameTime = MC.getFrameTime();
|
||||||
#else
|
#else
|
||||||
Vec3 colorValues = MC.level.getSkyColor(MC.gameRenderer.getMainCamera().getPosition(), MC.getFrameTime());
|
frameTime = MC.getTimer().getRealtimeDeltaTicks();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if MC_VER < MC_1_17_1
|
||||||
|
Vec3 colorValues = MC.level.getSkyColor(MC.gameRenderer.getMainCamera().getBlockPosition(), frameTime);
|
||||||
|
#else
|
||||||
|
Vec3 colorValues = MC.level.getSkyColor(MC.gameRenderer.getMainCamera().getPosition(), frameTime);
|
||||||
#endif
|
#endif
|
||||||
return new Color((float) colorValues.x, (float) colorValues.y, (float) colorValues.z);
|
return new Color((float) colorValues.x, (float) colorValues.y, (float) colorValues.z);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
return new Color(0, 0, 0);
|
return new Color(0, 0, 0);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double getFov(float partialTicks)
|
public double getFov(float partialTicks)
|
||||||
@@ -213,7 +239,7 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper
|
|||||||
@Override
|
@Override
|
||||||
public int getRenderDistance()
|
public int getRenderDistance()
|
||||||
{
|
{
|
||||||
#if PRE_MC_1_18_2
|
#if MC_VER < MC_1_18_2
|
||||||
//FIXME: How to resolve this?
|
//FIXME: How to resolve this?
|
||||||
return MC.options.renderDistance;
|
return MC.options.renderDistance;
|
||||||
#else
|
#else
|
||||||
@@ -261,12 +287,6 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper
|
|||||||
@Override
|
@Override
|
||||||
public int getTargetFrameBuffer()
|
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
|
// used so we can access the framebuffer shaders end up rendering to
|
||||||
if (AbstractOptifineAccessor.optifinePresent())
|
if (AbstractOptifineAccessor.optifinePresent())
|
||||||
{
|
{
|
||||||
@@ -321,25 +341,25 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
#if MC_1_20_2
|
#if MC_VER < MC_1_20_2
|
||||||
LevelRenderer levelRenderer = MC.levelRenderer;
|
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) -> {
|
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),
|
return new DhChunkPos(Math.floorDiv((int) chunkBoundingBox.minX, 16),
|
||||||
Math.floorDiv((int) chunkBoundingBox.minZ, 16));
|
Math.floorDiv((int) chunkBoundingBox.minZ, 16));
|
||||||
}).collect(Collectors.toCollection(HashSet::new)));
|
}).collect(Collectors.toCollection(HashSet::new)));
|
||||||
#else
|
#else
|
||||||
LevelRenderer levelRenderer = MC.levelRenderer;
|
LevelRenderer levelRenderer = MC.levelRenderer;
|
||||||
Collection<LevelRenderer.RenderChunkInfo> chunks =
|
Collection<SectionRenderDispatcher.RenderSection> chunks = levelRenderer.visibleSections;
|
||||||
#if PRE_MC_1_18_2 levelRenderer.renderChunks;
|
|
||||||
#else levelRenderer.renderChunkStorage.get().renderChunks; #endif
|
|
||||||
|
|
||||||
return (chunks.stream().map((chunk) -> {
|
return (chunks.stream().map((chunk) -> {
|
||||||
AABB chunkBoundingBox =
|
AABB chunkBoundingBox = chunk.getBoundingBox();
|
||||||
#if PRE_MC_1_18_2 chunk.chunk.bb;
|
|
||||||
#else chunk.chunk.getBoundingBox(); #endif
|
|
||||||
return new DhChunkPos(Math.floorDiv((int) chunkBoundingBox.minX, 16),
|
return new DhChunkPos(Math.floorDiv((int) chunkBoundingBox.minX, 16),
|
||||||
Math.floorDiv((int) chunkBoundingBox.minZ, 16));
|
Math.floorDiv((int) chunkBoundingBox.minZ, 16));
|
||||||
}).collect(Collectors.toCollection(HashSet::new)));
|
}).collect(Collectors.toCollection(HashSet::new)));
|
||||||
@@ -371,7 +391,7 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper
|
|||||||
@Override
|
@Override
|
||||||
public boolean isFogStateSpecial()
|
public boolean isFogStateSpecial()
|
||||||
{
|
{
|
||||||
#if PRE_MC_1_17_1
|
#if MC_VER < MC_1_17_1
|
||||||
Camera camera = Minecraft.getInstance().gameRenderer.getMainCamera();
|
Camera camera = Minecraft.getInstance().gameRenderer.getMainCamera();
|
||||||
FluidState fluidState = camera.getFluidInCamera();
|
FluidState fluidState = camera.getFluidInCamera();
|
||||||
Entity entity = camera.getEntity();
|
Entity entity = camera.getEntity();
|
||||||
@@ -392,11 +412,8 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper
|
|||||||
// so this will have to do for now
|
// so this will have to do for now
|
||||||
IDimensionTypeWrapper dimensionType = level.getDimensionType();
|
IDimensionTypeWrapper dimensionType = level.getDimensionType();
|
||||||
|
|
||||||
if (!this.lightmapByDimensionType.containsKey(dimensionType))
|
LightMapWrapper wrapper = this.lightmapByDimensionType.computeIfAbsent(dimensionType, (dimType) -> new LightMapWrapper());
|
||||||
{
|
wrapper.uploadLightmap(lightPixels);
|
||||||
this.lightmapByDimensionType.put(dimensionType, new LightMapWrapper());
|
|
||||||
}
|
|
||||||
this.lightmapByDimensionType.get(dimensionType).uploadLightmap(lightPixels);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+26
-22
@@ -25,38 +25,45 @@ import org.lwjgl.opengl.GL32;
|
|||||||
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
/**
|
|
||||||
* @author James Seibel
|
|
||||||
* @version 11-21-2021
|
|
||||||
*/
|
|
||||||
public class LightMapWrapper implements ILightMapWrapper
|
public class LightMapWrapper implements ILightMapWrapper
|
||||||
{
|
{
|
||||||
private int textureId = 0;
|
private int textureId = 0;
|
||||||
|
|
||||||
public LightMapWrapper()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
private void createLightmap(NativeImage image)
|
//==============//
|
||||||
{
|
// constructors //
|
||||||
textureId = GL32.glGenTextures();
|
//==============//
|
||||||
GL32.glBindTexture(GL32.GL_TEXTURE_2D, textureId);
|
|
||||||
GL32.glTexImage2D(GL32.GL_TEXTURE_2D, 0, image.format().glFormat(), image.getWidth(), image.getHeight(),
|
public LightMapWrapper() { }
|
||||||
0, image.format().glFormat(), GL32.GL_UNSIGNED_BYTE, (ByteBuffer) null);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
//=========//
|
||||||
|
// methods //
|
||||||
|
//=========//
|
||||||
|
|
||||||
public void uploadLightmap(NativeImage image)
|
public void uploadLightmap(NativeImage image)
|
||||||
{
|
{
|
||||||
int currentBind = GL32.glGetInteger(GL32.GL_TEXTURE_BINDING_2D);
|
int currentBind = GL32.glGetInteger(GL32.GL_TEXTURE_BINDING_2D);
|
||||||
GL32.glBindTexture(GL32.GL_TEXTURE_2D, textureId);
|
if (this.textureId == 0)
|
||||||
if (textureId == 0)
|
|
||||||
{
|
{
|
||||||
createLightmap(image);
|
this.createLightmap(image);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GL32.glBindTexture(GL32.GL_TEXTURE_2D, this.textureId);
|
||||||
}
|
}
|
||||||
// NativeImage::upload(int levelOfDetail, int xOffset, int yOffset, bool shouldCleanup?)
|
|
||||||
image.upload(0, 0, 0, false);
|
image.upload(0, 0, 0, false);
|
||||||
GL32.glBindTexture(GL32.GL_TEXTURE_2D, currentBind);
|
GL32.glBindTexture(GL32.GL_TEXTURE_2D, currentBind);
|
||||||
}
|
}
|
||||||
|
private void createLightmap(NativeImage image)
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void bind()
|
public void bind()
|
||||||
@@ -66,9 +73,6 @@ public class LightMapWrapper implements ILightMapWrapper
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void unbind()
|
public void unbind() { GL32.glBindTexture(GL32.GL_TEXTURE_2D, 0); }
|
||||||
{
|
|
||||||
GL32.glBindTexture(GL32.GL_TEXTURE_2D, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -33,7 +33,7 @@ public class ServerPlayerWrapper implements IServerPlayerWrapper
|
|||||||
|
|
||||||
public IServerLevelWrapper getLevel()
|
public IServerLevelWrapper getLevel()
|
||||||
{
|
{
|
||||||
#if PRE_MC_1_20_1
|
#if MC_VER < MC_1_20_1
|
||||||
return ServerLevelWrapper.getWrapper(this.serverPlayer.getLevel());
|
return ServerLevelWrapper.getWrapper(this.serverPlayer.getLevel());
|
||||||
#else
|
#else
|
||||||
return ServerLevelWrapper.getWrapper(this.serverPlayer.serverLevel());
|
return ServerLevelWrapper.getWrapper(this.serverPlayer.serverLevel());
|
||||||
|
|||||||
+92
-10
@@ -1,7 +1,7 @@
|
|||||||
package com.seibel.distanthorizons.common.wrappers.world;
|
package com.seibel.distanthorizons.common.wrappers.world;
|
||||||
|
|
||||||
import com.seibel.distanthorizons.api.enums.worldGeneration.EDhApiLevelType;
|
import com.seibel.distanthorizons.api.enums.worldGeneration.EDhApiLevelType;
|
||||||
import com.seibel.distanthorizons.api.interfaces.world.IDhApiDimensionTypeWrapper;
|
import com.seibel.distanthorizons.api.interfaces.render.IDhApiCustomRenderRegister;
|
||||||
import com.seibel.distanthorizons.common.wrappers.McObjectConverter;
|
import com.seibel.distanthorizons.common.wrappers.McObjectConverter;
|
||||||
import com.seibel.distanthorizons.common.wrappers.block.BiomeWrapper;
|
import com.seibel.distanthorizons.common.wrappers.block.BiomeWrapper;
|
||||||
import com.seibel.distanthorizons.common.wrappers.block.BlockStateWrapper;
|
import com.seibel.distanthorizons.common.wrappers.block.BlockStateWrapper;
|
||||||
@@ -9,7 +9,7 @@ import com.seibel.distanthorizons.common.wrappers.block.cache.ClientBlockDetailM
|
|||||||
import com.seibel.distanthorizons.common.wrappers.chunk.ChunkWrapper;
|
import com.seibel.distanthorizons.common.wrappers.chunk.ChunkWrapper;
|
||||||
import com.seibel.distanthorizons.common.wrappers.minecraft.MinecraftClientWrapper;
|
import com.seibel.distanthorizons.common.wrappers.minecraft.MinecraftClientWrapper;
|
||||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||||
import com.seibel.distanthorizons.core.level.IKeyedClientLevelManager;
|
import com.seibel.distanthorizons.core.level.*;
|
||||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||||
import com.seibel.distanthorizons.core.pos.DhBlockPos;
|
import com.seibel.distanthorizons.core.pos.DhBlockPos;
|
||||||
import com.seibel.distanthorizons.core.pos.DhChunkPos;
|
import com.seibel.distanthorizons.core.pos.DhChunkPos;
|
||||||
@@ -19,28 +19,40 @@ import com.seibel.distanthorizons.core.wrapperInterfaces.world.IBiomeWrapper;
|
|||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IDimensionTypeWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IDimensionTypeWrapper;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IServerLevelWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IServerLevelWrapper;
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.multiplayer.ClientLevel;
|
import net.minecraft.client.multiplayer.ClientLevel;
|
||||||
import net.minecraft.core.BlockPos;
|
|
||||||
import net.minecraft.server.level.ServerLevel;
|
import net.minecraft.server.level.ServerLevel;
|
||||||
import net.minecraft.world.level.LightLayer;
|
|
||||||
import net.minecraft.world.level.chunk.ChunkAccess;
|
import net.minecraft.world.level.chunk.ChunkAccess;
|
||||||
import net.minecraft.world.level.chunk.ChunkSource;
|
import net.minecraft.world.level.chunk.ChunkSource;
|
||||||
import net.minecraft.world.level.chunk.ChunkStatus;
|
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
#if MC_VER <= MC_1_20_4
|
||||||
|
import net.minecraft.world.level.chunk.ChunkStatus;
|
||||||
|
#else
|
||||||
|
import net.minecraft.world.level.chunk.status.ChunkStatus;
|
||||||
|
#endif
|
||||||
|
|
||||||
public class ClientLevelWrapper implements IClientLevelWrapper
|
public class ClientLevelWrapper implements IClientLevelWrapper
|
||||||
{
|
{
|
||||||
private static final Logger LOGGER = DhLoggerBuilder.getLogger(ClientLevelWrapper.class.getSimpleName());
|
private static final Logger LOGGER = DhLoggerBuilder.getLogger(ClientLevelWrapper.class.getSimpleName());
|
||||||
private static final ConcurrentHashMap<ClientLevel, ClientLevelWrapper> LEVEL_WRAPPER_BY_CLIENT_LEVEL = new ConcurrentHashMap<>();
|
private static final ConcurrentHashMap<ClientLevel, ClientLevelWrapper> LEVEL_WRAPPER_BY_CLIENT_LEVEL = new ConcurrentHashMap<>(); // TODO can leak
|
||||||
private static final IKeyedClientLevelManager KEYED_CLIENT_LEVEL_MANAGER = SingletonInjector.INSTANCE.get(IKeyedClientLevelManager.class);
|
private static final IKeyedClientLevelManager KEYED_CLIENT_LEVEL_MANAGER = SingletonInjector.INSTANCE.get(IKeyedClientLevelManager.class);
|
||||||
|
|
||||||
|
private static final Minecraft MINECRAFT = Minecraft.getInstance();
|
||||||
|
|
||||||
private final ClientLevel level;
|
private final ClientLevel level;
|
||||||
private final ClientBlockDetailMap blockMap = new ClientBlockDetailMap(this);
|
private final ClientBlockDetailMap blockMap = new ClientBlockDetailMap(this);
|
||||||
|
|
||||||
|
private BlockStateWrapper dirtBlockWrapper;
|
||||||
|
private BiomeWrapper plainsBiomeWrapper;
|
||||||
|
@Deprecated // TODO circular references are bad
|
||||||
|
private IDhLevel parentDhLevel;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//=============//
|
//=============//
|
||||||
@@ -79,7 +91,7 @@ public class ClientLevelWrapper implements IClientLevelWrapper
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Iterable<ServerLevel> serverLevels = MinecraftClientWrapper.INSTANCE.mc.getSingleplayerServer().getAllLevels();
|
Iterable<ServerLevel> serverLevels = MINECRAFT.getSingleplayerServer().getAllLevels();
|
||||||
|
|
||||||
// attempt to find the server level with the same dimension type
|
// attempt to find the server level with the same dimension type
|
||||||
// TODO this assumes only one level per dimension type, the SubDimensionLevelMatcher will need to be added for supporting multiple levels per dimension
|
// TODO this assumes only one level per dimension type, the SubDimensionLevelMatcher will need to be added for supporting multiple levels per dimension
|
||||||
@@ -116,6 +128,46 @@ public class ClientLevelWrapper implements IClientLevelWrapper
|
|||||||
return this.blockMap.getColor(((BlockStateWrapper) blockState).blockState, (BiomeWrapper) biome, pos);
|
return this.blockMap.getColor(((BlockStateWrapper) blockState).blockState, (BiomeWrapper) biome, pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getDirtBlockColor()
|
||||||
|
{
|
||||||
|
if (this.dirtBlockWrapper == null)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
this.dirtBlockWrapper = (BlockStateWrapper) BlockStateWrapper.deserialize(BlockStateWrapper.DIRT_RESOURCE_LOCATION_STRING, this);
|
||||||
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
// shouldn't happen, but just in case
|
||||||
|
LOGGER.warn("Unable to get dirt color with resource location ["+BlockStateWrapper.DIRT_RESOURCE_LOCATION_STRING+"] with level ["+this+"].", e);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.blockMap.getColor(this.dirtBlockWrapper.blockState, BiomeWrapper.EMPTY_WRAPPER, DhBlockPos.ZERO);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IBiomeWrapper getPlainsBiomeWrapper()
|
||||||
|
{
|
||||||
|
if (this.plainsBiomeWrapper == null)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
this.plainsBiomeWrapper = (BiomeWrapper) BiomeWrapper.deserialize(BiomeWrapper.PLAINS_RESOURCE_LOCATION_STRING, this);
|
||||||
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
// shouldn't happen, but just in case
|
||||||
|
LOGGER.warn("Unable to get planes biome with resource location ["+BiomeWrapper.PLAINS_RESOURCE_LOCATION_STRING+"] with level ["+this+"].", e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.plainsBiomeWrapper;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IDimensionTypeWrapper getDimensionType() { return DimensionTypeWrapper.getDimensionTypeWrapper(this.level.dimensionType()); }
|
public IDimensionTypeWrapper getDimensionType() { return DimensionTypeWrapper.getDimensionTypeWrapper(this.level.dimensionType()); }
|
||||||
|
|
||||||
@@ -131,12 +183,12 @@ public class ClientLevelWrapper implements IClientLevelWrapper
|
|||||||
public boolean hasSkyLight() { return this.level.dimensionType().hasSkyLight(); }
|
public boolean hasSkyLight() { return this.level.dimensionType().hasSkyLight(); }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getHeight() { return this.level.getHeight(); }
|
public int getMaxHeight() { return this.level.getHeight(); }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getMinHeight()
|
public int getMinHeight()
|
||||||
{
|
{
|
||||||
#if PRE_MC_1_17_1
|
#if MC_VER < MC_1_17_1
|
||||||
return 0;
|
return 0;
|
||||||
#else
|
#else
|
||||||
return this.level.getMinBuildHeight();
|
return this.level.getMinBuildHeight();
|
||||||
@@ -180,7 +232,37 @@ public class ClientLevelWrapper implements IClientLevelWrapper
|
|||||||
public ClientLevel getWrappedMcObject() { return this.level; }
|
public ClientLevel getWrappedMcObject() { return this.level; }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onUnload() { LEVEL_WRAPPER_BY_CLIENT_LEVEL.remove(this.level); }
|
public void onUnload()
|
||||||
|
{
|
||||||
|
LEVEL_WRAPPER_BY_CLIENT_LEVEL.remove(this.level);
|
||||||
|
this.parentDhLevel = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//===================//
|
||||||
|
// generic rendering //
|
||||||
|
//===================//
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setParentLevel(IDhLevel parentLevel) { this.parentDhLevel = parentLevel; }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IDhApiCustomRenderRegister getRenderRegister()
|
||||||
|
{
|
||||||
|
if (this.parentDhLevel == null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.parentDhLevel.getGenericRenderer();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//================//
|
||||||
|
// base overrides //
|
||||||
|
//================//
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString()
|
public String toString()
|
||||||
|
|||||||
+34
-23
@@ -23,12 +23,14 @@ import java.io.File;
|
|||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
import com.seibel.distanthorizons.api.enums.worldGeneration.EDhApiLevelType;
|
import com.seibel.distanthorizons.api.enums.worldGeneration.EDhApiLevelType;
|
||||||
|
import com.seibel.distanthorizons.api.interfaces.render.IDhApiCustomRenderRegister;
|
||||||
import com.seibel.distanthorizons.common.wrappers.McObjectConverter;
|
import com.seibel.distanthorizons.common.wrappers.McObjectConverter;
|
||||||
import com.seibel.distanthorizons.common.wrappers.block.BiomeWrapper;
|
import com.seibel.distanthorizons.common.wrappers.block.BiomeWrapper;
|
||||||
import com.seibel.distanthorizons.common.wrappers.block.BlockStateWrapper;
|
import com.seibel.distanthorizons.common.wrappers.block.BlockStateWrapper;
|
||||||
import com.seibel.distanthorizons.common.wrappers.block.cache.ServerBlockDetailMap;
|
import com.seibel.distanthorizons.common.wrappers.block.cache.ServerBlockDetailMap;
|
||||||
import com.seibel.distanthorizons.common.wrappers.chunk.ChunkWrapper;
|
import com.seibel.distanthorizons.common.wrappers.chunk.ChunkWrapper;
|
||||||
import com.seibel.distanthorizons.common.wrappers.minecraft.MinecraftClientWrapper;
|
import com.seibel.distanthorizons.common.wrappers.minecraft.MinecraftClientWrapper;
|
||||||
|
import com.seibel.distanthorizons.core.level.IDhLevel;
|
||||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||||
import com.seibel.distanthorizons.core.pos.DhBlockPos;
|
import com.seibel.distanthorizons.core.pos.DhBlockPos;
|
||||||
import com.seibel.distanthorizons.core.pos.DhChunkPos;
|
import com.seibel.distanthorizons.core.pos.DhChunkPos;
|
||||||
@@ -41,7 +43,12 @@ import com.seibel.distanthorizons.core.wrapperInterfaces.world.IServerLevelWrapp
|
|||||||
import net.minecraft.server.level.ServerLevel;
|
import net.minecraft.server.level.ServerLevel;
|
||||||
import net.minecraft.world.level.chunk.ChunkAccess;
|
import net.minecraft.world.level.chunk.ChunkAccess;
|
||||||
import net.minecraft.world.level.chunk.ChunkSource;
|
import net.minecraft.world.level.chunk.ChunkSource;
|
||||||
|
|
||||||
|
#if MC_VER <= MC_1_20_4
|
||||||
import net.minecraft.world.level.chunk.ChunkStatus;
|
import net.minecraft.world.level.chunk.ChunkStatus;
|
||||||
|
#else
|
||||||
|
import net.minecraft.world.level.chunk.status.ChunkStatus;
|
||||||
|
#endif
|
||||||
|
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
@@ -54,8 +61,9 @@ public class ServerLevelWrapper implements IServerLevelWrapper
|
|||||||
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
|
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
|
||||||
private static final ConcurrentHashMap<ServerLevel, ServerLevelWrapper> LEVEL_WRAPPER_BY_SERVER_LEVEL = new ConcurrentHashMap<>();
|
private static final ConcurrentHashMap<ServerLevel, ServerLevelWrapper> LEVEL_WRAPPER_BY_SERVER_LEVEL = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
final ServerLevel level;
|
private final ServerLevel level;
|
||||||
ServerBlockDetailMap blockMap = new ServerBlockDetailMap(this);
|
@Deprecated // TODO circular references are bad
|
||||||
|
private IDhLevel parentDhLevel;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -76,19 +84,6 @@ public class ServerLevelWrapper implements IServerLevelWrapper
|
|||||||
// methods //
|
// methods //
|
||||||
//=========//
|
//=========//
|
||||||
|
|
||||||
@Nullable
|
|
||||||
@Override
|
|
||||||
public IClientLevelWrapper tryGetClientLevelWrapper()
|
|
||||||
{
|
|
||||||
MinecraftClientWrapper client = MinecraftClientWrapper.INSTANCE;
|
|
||||||
if (client.mc.level == null)
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ClientLevelWrapper.getWrapper(client.mc.level);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public File getSaveFolder()
|
public File getSaveFolder()
|
||||||
{
|
{
|
||||||
@@ -122,7 +117,7 @@ public class ServerLevelWrapper implements IServerLevelWrapper
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getHeight()
|
public int getMaxHeight()
|
||||||
{
|
{
|
||||||
return level.getHeight();
|
return level.getHeight();
|
||||||
}
|
}
|
||||||
@@ -130,12 +125,13 @@ public class ServerLevelWrapper implements IServerLevelWrapper
|
|||||||
@Override
|
@Override
|
||||||
public int getMinHeight()
|
public int getMinHeight()
|
||||||
{
|
{
|
||||||
#if PRE_MC_1_17_1
|
#if MC_VER < MC_1_17_1
|
||||||
return 0;
|
return 0;
|
||||||
#else
|
#else
|
||||||
return level.getMinBuildHeight();
|
return level.getMinBuildHeight();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IChunkWrapper tryGetChunk(DhChunkPos pos)
|
public IChunkWrapper tryGetChunk(DhChunkPos pos)
|
||||||
{
|
{
|
||||||
@@ -166,18 +162,33 @@ public class ServerLevelWrapper implements IServerLevelWrapper
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ServerLevel getWrappedMcObject()
|
public ServerLevel getWrappedMcObject() { return this.level; }
|
||||||
{
|
|
||||||
return level;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onUnload() { LEVEL_WRAPPER_BY_SERVER_LEVEL.remove(this.level); }
|
public void onUnload() { LEVEL_WRAPPER_BY_SERVER_LEVEL.remove(this.level); }
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString()
|
public void setParentLevel(IDhLevel parentLevel) { this.parentDhLevel = parentLevel; }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IDhApiCustomRenderRegister getRenderRegister()
|
||||||
{
|
{
|
||||||
return "Wrapped{" + level.toString() + "@" + getDimensionType().getDimensionName() + "}";
|
if (this.parentDhLevel == null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return this.parentDhLevel.getGenericRenderer();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//================//
|
||||||
|
// base overrides //
|
||||||
|
//================//
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() { return "Wrapped{" + this.level.toString() + "@" + this.getDimensionType().getDimensionName() + "}"; }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+211
-98
@@ -35,6 +35,7 @@ import com.seibel.distanthorizons.core.pos.DhChunkPos;
|
|||||||
import com.seibel.distanthorizons.core.util.objects.EventTimer;
|
import com.seibel.distanthorizons.core.util.objects.EventTimer;
|
||||||
import com.seibel.distanthorizons.core.util.LodUtil;
|
import com.seibel.distanthorizons.core.util.LodUtil;
|
||||||
import com.seibel.distanthorizons.core.util.gridList.ArrayGridList;
|
import com.seibel.distanthorizons.core.util.gridList.ArrayGridList;
|
||||||
|
import com.seibel.distanthorizons.core.wrapperInterfaces.chunk.ChunkLightStorage;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.chunk.IChunkWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.chunk.IChunkWrapper;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.worldGeneration.AbstractBatchGenerationEnvironmentWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.worldGeneration.AbstractBatchGenerationEnvironmentWrapper;
|
||||||
import com.seibel.distanthorizons.common.wrappers.chunk.ChunkWrapper;
|
import com.seibel.distanthorizons.common.wrappers.chunk.ChunkWrapper;
|
||||||
@@ -56,7 +57,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.StepStructureStart;
|
||||||
import com.seibel.distanthorizons.common.wrappers.worldGeneration.step.StepSurface;
|
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;
|
import net.minecraft.core.registries.Registries;
|
||||||
#else
|
#else
|
||||||
import net.minecraft.core.Registry;
|
import net.minecraft.core.Registry;
|
||||||
@@ -66,10 +67,10 @@ import net.minecraft.server.level.ServerLevel;
|
|||||||
import net.minecraft.world.level.ChunkPos;
|
import net.minecraft.world.level.ChunkPos;
|
||||||
import net.minecraft.world.level.chunk.ChunkAccess;
|
import net.minecraft.world.level.chunk.ChunkAccess;
|
||||||
import net.minecraft.world.level.chunk.ChunkGenerator;
|
import net.minecraft.world.level.chunk.ChunkGenerator;
|
||||||
import net.minecraft.world.level.chunk.ChunkStatus;
|
|
||||||
import net.minecraft.world.level.chunk.LevelChunk;
|
import net.minecraft.world.level.chunk.LevelChunk;
|
||||||
import net.minecraft.world.level.chunk.ProtoChunk;
|
import net.minecraft.world.level.chunk.ProtoChunk;
|
||||||
import net.minecraft.world.level.chunk.UpgradeData;
|
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.chunk.storage.RegionFileStorage;
|
||||||
import net.minecraft.world.level.levelgen.DebugLevelSource;
|
import net.minecraft.world.level.levelgen.DebugLevelSource;
|
||||||
import net.minecraft.world.level.levelgen.FlatLevelSource;
|
import net.minecraft.world.level.levelgen.FlatLevelSource;
|
||||||
@@ -78,6 +79,12 @@ import net.minecraft.world.level.levelgen.NoiseBasedChunkGenerator;
|
|||||||
import net.minecraft.nbt.CompoundTag;
|
import net.minecraft.nbt.CompoundTag;
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
|
||||||
|
#if MC_VER <= MC_1_20_4
|
||||||
|
import net.minecraft.world.level.chunk.ChunkStatus;
|
||||||
|
#else
|
||||||
|
import net.minecraft.world.level.chunk.status.ChunkStatus;
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Total: 3.135214124s
|
Total: 3.135214124s
|
||||||
=====================================
|
=====================================
|
||||||
@@ -103,8 +110,6 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
|
|||||||
new ConfigBasedLogger(LogManager.getLogger("LodWorldGen"),
|
new ConfigBasedLogger(LogManager.getLogger("LodWorldGen"),
|
||||||
() -> Config.Client.Advanced.Logging.logWorldGenLoadEvent.get());
|
() -> Config.Client.Advanced.Logging.logWorldGenLoadEvent.get());
|
||||||
|
|
||||||
//TODO: Make actual proper support for StarLight
|
|
||||||
|
|
||||||
public static class PerfCalculator
|
public static class PerfCalculator
|
||||||
{
|
{
|
||||||
private static final String[] TIME_NAMES = {
|
private static final String[] TIME_NAMES = {
|
||||||
@@ -142,7 +147,7 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
|
|||||||
if (index == -1) continue;
|
if (index == -1) continue;
|
||||||
times.get(index).add(e.timeNs);
|
times.get(index).add(e.timeNs);
|
||||||
}
|
}
|
||||||
times.get(0).add(event.getTotalTimeNs());
|
times.getFirst().add(event.getTotalTimeNs());
|
||||||
}
|
}
|
||||||
|
|
||||||
public String toString()
|
public String toString()
|
||||||
@@ -288,6 +293,9 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//=================//
|
||||||
|
// synchronization //
|
||||||
|
//=================//
|
||||||
|
|
||||||
public <T> T joinSync(CompletableFuture<T> future)
|
public <T> T joinSync(CompletableFuture<T> future)
|
||||||
{
|
{
|
||||||
@@ -338,8 +346,11 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
|
|||||||
}
|
}
|
||||||
else if (event.hasTimeout(Config.Client.Advanced.WorldGenerator.worldGenerationTimeoutLengthInSeconds.get(), TimeUnit.SECONDS))
|
else if (event.hasTimeout(Config.Client.Advanced.WorldGenerator.worldGenerationTimeoutLengthInSeconds.get(), TimeUnit.SECONDS))
|
||||||
{
|
{
|
||||||
EVENT_LOGGER.error("Batching World Generator: " + event + " timed out and terminated!");
|
EVENT_LOGGER.warn(
|
||||||
EVENT_LOGGER.info("Dump PrefEvent: " + event.timer);
|
"Batching World Generator: [" + event + "] timed out and terminated after ["+Config.Client.Advanced.WorldGenerator.worldGenerationTimeoutLengthInSeconds.get()+"] seconds. " +
|
||||||
|
"\nYour computer might be overloaded or your world gen mods might be causing world gen to take longer than expected. " +
|
||||||
|
"\nEither increase DH's world gen timeout or reduce your computer's CPU load.");
|
||||||
|
EVENT_LOGGER.debug("Dump PrefEvent: " + event.timer);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (!event.terminate())
|
if (!event.terminate())
|
||||||
@@ -362,69 +373,11 @@ 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
|
|
||||||
Registry.BIOME_REGISTRY
|
|
||||||
#else
|
|
||||||
Registries.BIOME
|
|
||||||
#endif
|
|
||||||
), null #endif
|
|
||||||
);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public ChunkAccess loadOrMakeChunk(ChunkPos chunkPos)
|
//==================//
|
||||||
{
|
// world generation //
|
||||||
ServerLevel level = this.params.level;
|
//==================//
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
RegionFileStorage storage = this.params.level.getChunkSource().chunkMap.worker.storage;
|
|
||||||
RegionFileStorageExternalCache cache = this.getOrCreateRegionFileCache(storage);
|
|
||||||
chunkData = cache.read(chunkPos);
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
LOAD_LOGGER.error("DistantHorizons: Couldn't load or make chunk " + chunkPos + ". Error: " + e.getMessage(), e);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (chunkData == null)
|
|
||||||
{
|
|
||||||
return EmptyChunk(level, chunkPos);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
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);
|
|
||||||
return EmptyChunk(level, chunkPos);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static <T> ArrayGridList<T> GetCutoutFrom(ArrayGridList<T> total, int border)
|
|
||||||
{
|
|
||||||
return new ArrayGridList<>(total, border, total.gridSize - border);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static <T> ArrayGridList<T> GetCutoutFrom(ArrayGridList<T> total, EDhApiWorldGenerationStep step)
|
|
||||||
{
|
|
||||||
return GetCutoutFrom(total, MaxBorderNeeded - BorderNeeded.get(step));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void generateLodFromList(GenerationEvent genEvent) throws InterruptedException
|
public void generateLodFromList(GenerationEvent genEvent) throws InterruptedException
|
||||||
{
|
{
|
||||||
@@ -432,7 +385,7 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
|
|||||||
|
|
||||||
ArrayGridList<ChunkWrapper> chunkWrapperList;
|
ArrayGridList<ChunkWrapper> chunkWrapperList;
|
||||||
DhLitWorldGenRegion region;
|
DhLitWorldGenRegion region;
|
||||||
DummyLightEngine lightEngine;
|
DummyLightEngine dummyLightEngine;
|
||||||
LightGetterAdaptor adaptor;
|
LightGetterAdaptor adaptor;
|
||||||
|
|
||||||
int borderSize = MaxBorderNeeded;
|
int borderSize = MaxBorderNeeded;
|
||||||
@@ -445,50 +398,102 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
|
|||||||
ArrayGridList<ChunkAccess> totalChunks;
|
ArrayGridList<ChunkAccess> totalChunks;
|
||||||
|
|
||||||
adaptor = new LightGetterAdaptor(this.params.level);
|
adaptor = new LightGetterAdaptor(this.params.level);
|
||||||
lightEngine = new DummyLightEngine(adaptor);
|
dummyLightEngine = new DummyLightEngine(adaptor);
|
||||||
|
|
||||||
EmptyChunkGenerator generator = (int x, int z) ->
|
|
||||||
|
|
||||||
|
//=============================//
|
||||||
|
// try getting existing chunks //
|
||||||
|
//=============================//
|
||||||
|
|
||||||
|
HashMap<DhChunkPos, ChunkLightStorage> chunkSkyLightingByDhPos = new HashMap<>();
|
||||||
|
HashMap<DhChunkPos, ChunkLightStorage> chunkBlockLightingByDhPos = new HashMap<>();
|
||||||
|
IEmptyChunkGeneratorFunc emptyChunkGeneratorFunc = (int x, int z) ->
|
||||||
{
|
{
|
||||||
ChunkPos chunkPos = new ChunkPos(x, z);
|
ChunkPos chunkPos = new ChunkPos(x, z);
|
||||||
ChunkAccess target = null;
|
DhChunkPos dhChunkPos = new DhChunkPos(x, z);
|
||||||
|
ChunkAccess newChunk = null;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
target = this.loadOrMakeChunk(chunkPos);
|
// get the chunk
|
||||||
|
CompoundTag chunkData = this.getChunkNbtData(chunkPos);
|
||||||
|
newChunk = this.loadOrMakeChunk(chunkPos, chunkData);
|
||||||
|
|
||||||
|
if (Config.Client.Advanced.LodBuilding.pullLightingForPregeneratedChunks.get())
|
||||||
|
{
|
||||||
|
// attempt to get chunk lighting
|
||||||
|
ChunkLoader.CombinedChunkLightStorage combinedLights = ChunkLoader.readLight(newChunk, chunkData);
|
||||||
|
if (combinedLights != null)
|
||||||
|
{
|
||||||
|
chunkSkyLightingByDhPos.put(dhChunkPos, combinedLights.skyLightStorage);
|
||||||
|
chunkBlockLightingByDhPos.put(dhChunkPos, combinedLights.blockLightStorage);
|
||||||
}
|
}
|
||||||
catch (RuntimeException e2)
|
}
|
||||||
|
}
|
||||||
|
catch (RuntimeException loadChunkError)
|
||||||
{
|
{
|
||||||
// Continue...
|
// Continue...
|
||||||
}
|
}
|
||||||
|
|
||||||
if (target == null)
|
if (newChunk == null)
|
||||||
{
|
{
|
||||||
target = new ProtoChunk(chunkPos, UpgradeData.EMPTY
|
newChunk = new ProtoChunk(chunkPos, UpgradeData.EMPTY
|
||||||
#if POST_MC_1_17_1 , params.level #endif
|
#if MC_VER >= MC_1_17_1 , this.params.level #endif
|
||||||
#if POST_MC_1_18_2 , params.biomes, null #endif
|
#if MC_VER >= MC_1_18_2 , this.params.biomes, null #endif
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return target;
|
return newChunk;
|
||||||
};
|
};
|
||||||
|
totalChunks = new ArrayGridList<>(refSize, (x, z) -> emptyChunkGeneratorFunc.generate(x + refPosX, z + refPosZ));
|
||||||
|
|
||||||
totalChunks = new ArrayGridList<>(refSize, (x, z) -> generator.generate(x + refPosX, z + refPosZ));
|
int radius = refSize / 2;
|
||||||
|
int centerX = refPosX + radius;
|
||||||
|
int centerZ = refPosZ + radius;
|
||||||
|
|
||||||
|
ChunkAccess centerChunk = totalChunks.stream().filter(chunk -> chunk.getPos().x == centerX && chunk.getPos().z == centerZ).findFirst().get();
|
||||||
|
|
||||||
genEvent.refreshTimeout();
|
genEvent.refreshTimeout();
|
||||||
region = new DhLitWorldGenRegion(params.level, lightEngine, totalChunks,
|
region = new DhLitWorldGenRegion(
|
||||||
ChunkStatus.STRUCTURE_STARTS, refSize / 2, generator);
|
centerX, centerZ,
|
||||||
|
centerChunk,
|
||||||
|
this.params.level, dummyLightEngine, totalChunks,
|
||||||
|
ChunkStatus.STRUCTURE_STARTS, radius, emptyChunkGeneratorFunc);
|
||||||
adaptor.setRegion(region);
|
adaptor.setRegion(region);
|
||||||
genEvent.threadedParam.makeStructFeat(region, params);
|
genEvent.threadedParam.makeStructFeat(region, this.params);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//=======================//
|
||||||
|
// create chunk wrappers //
|
||||||
|
//=======================//
|
||||||
|
|
||||||
chunkWrapperList = new ArrayGridList<>(totalChunks.gridSize);
|
chunkWrapperList = new ArrayGridList<>(totalChunks.gridSize);
|
||||||
totalChunks.forEachPos((x, z) ->
|
totalChunks.forEachPos((x, z) ->
|
||||||
{
|
{
|
||||||
ChunkAccess chunk = totalChunks.get(x, z);
|
ChunkAccess chunk = totalChunks.get(x, z);
|
||||||
if (chunk != null)
|
if (chunk != null)
|
||||||
{
|
{
|
||||||
chunkWrapperList.set(x, z, new ChunkWrapper(chunk, region, serverlevel.getLevelWrapper()));
|
// wrap the chunk
|
||||||
|
ChunkWrapper chunkWrapper = new ChunkWrapper(chunk, region, this.serverlevel.getLevelWrapper());
|
||||||
|
chunkWrapperList.set(x, z, chunkWrapper);
|
||||||
|
|
||||||
|
// try setting the wrapper's lighting
|
||||||
|
if (chunkBlockLightingByDhPos.containsKey(chunkWrapper.getChunkPos()))
|
||||||
|
{
|
||||||
|
chunkWrapper.setBlockLightStorage(chunkBlockLightingByDhPos.get(chunkWrapper.getChunkPos()));
|
||||||
|
chunkWrapper.setSkyLightStorage(chunkSkyLightingByDhPos.get(chunkWrapper.getChunkPos()));
|
||||||
|
chunkWrapper.setUseDhLighting(true);
|
||||||
|
chunkWrapper.setIsDhLightCorrect(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//=================//
|
||||||
|
// generate chunks //
|
||||||
|
//=================//
|
||||||
|
|
||||||
this.generateDirect(genEvent, chunkWrapperList, borderSize, genEvent.targetGenerationStep, region);
|
this.generateDirect(genEvent, chunkWrapperList, borderSize, genEvent.targetGenerationStep, region);
|
||||||
genEvent.timer.nextEvent("cleanup");
|
genEvent.timer.nextEvent("cleanup");
|
||||||
}
|
}
|
||||||
@@ -507,7 +512,7 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
|
|||||||
ChunkAccess target = wrappedChunk.getChunk();
|
ChunkAccess target = wrappedChunk.getChunk();
|
||||||
if (target instanceof LevelChunk)
|
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);
|
((LevelChunk) target).setLoaded(true);
|
||||||
#else
|
#else
|
||||||
((LevelChunk) target).loaded = true;
|
((LevelChunk) target).loaded = true;
|
||||||
@@ -519,8 +524,8 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
|
|||||||
throw new RuntimeException("The generated chunk somehow has isLightCorrect() returning false");
|
throw new RuntimeException("The generated chunk somehow has isLightCorrect() returning false");
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean isFull = target.getStatus() == ChunkStatus.FULL || target instanceof LevelChunk;
|
boolean isFull = ChunkWrapper.getStatus(target) == ChunkStatus.FULL || target instanceof LevelChunk;
|
||||||
#if POST_MC_1_18_2
|
#if MC_VER >= MC_1_18_2
|
||||||
boolean isPartial = target.isOldNoiseGeneration();
|
boolean isPartial = target.isOldNoiseGeneration();
|
||||||
#endif
|
#endif
|
||||||
if (isFull)
|
if (isFull)
|
||||||
@@ -528,14 +533,14 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
|
|||||||
LOAD_LOGGER.info("Detected full existing chunk at {}", target.getPos());
|
LOAD_LOGGER.info("Detected full existing chunk at {}", target.getPos());
|
||||||
genEvent.resultConsumer.accept(wrappedChunk);
|
genEvent.resultConsumer.accept(wrappedChunk);
|
||||||
}
|
}
|
||||||
#if POST_MC_1_18_2
|
#if MC_VER >= MC_1_18_2
|
||||||
else if (isPartial)
|
else if (isPartial)
|
||||||
{
|
{
|
||||||
LOAD_LOGGER.info("Detected old existing chunk at {}", target.getPos());
|
LOAD_LOGGER.info("Detected old existing chunk at {}", target.getPos());
|
||||||
genEvent.resultConsumer.accept(wrappedChunk);
|
genEvent.resultConsumer.accept(wrappedChunk);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
else if (target.getStatus() == ChunkStatus.EMPTY)
|
else if (ChunkWrapper.getStatus(target) == ChunkStatus.EMPTY)
|
||||||
{
|
{
|
||||||
genEvent.resultConsumer.accept(wrappedChunk);
|
genEvent.resultConsumer.accept(wrappedChunk);
|
||||||
}
|
}
|
||||||
@@ -554,6 +559,85 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
|
|||||||
PREF_LOGGER.infoInc("{}", genEvent.timer);
|
PREF_LOGGER.infoInc("{}", genEvent.timer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
private CompoundTag getChunkNbtData(ChunkPos chunkPos)
|
||||||
|
{
|
||||||
|
ServerLevel level = this.params.level;
|
||||||
|
|
||||||
|
CompoundTag chunkData = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
IOWorker ioWorker = level.getChunkSource().chunkMap.worker;
|
||||||
|
|
||||||
|
#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);
|
||||||
|
}
|
||||||
|
|
||||||
|
return chunkData;
|
||||||
|
}
|
||||||
|
private ChunkAccess loadOrMakeChunk(ChunkPos chunkPos, CompoundTag chunkData)
|
||||||
|
{
|
||||||
|
ServerLevel level = this.params.level;
|
||||||
|
|
||||||
|
if (chunkData == null)
|
||||||
|
{
|
||||||
|
return CreateEmptyChunk(level, chunkPos);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
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 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 CreateEmptyChunk(level, chunkPos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private static ProtoChunk CreateEmptyChunk(ServerLevel level, ChunkPos chunkPos)
|
||||||
|
{
|
||||||
|
return new ProtoChunk(chunkPos, UpgradeData.EMPTY
|
||||||
|
#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
|
||||||
|
#endif
|
||||||
|
), null #endif
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
public void generateDirect(
|
public void generateDirect(
|
||||||
GenerationEvent genEvent, ArrayGridList<ChunkWrapper> chunksToGenerate, int border,
|
GenerationEvent genEvent, ArrayGridList<ChunkWrapper> chunksToGenerate, int border,
|
||||||
@@ -569,9 +653,8 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
|
|||||||
chunksToGenerate.forEach((chunkWrapper) ->
|
chunksToGenerate.forEach((chunkWrapper) ->
|
||||||
{
|
{
|
||||||
ChunkAccess chunk = chunkWrapper.getChunk();
|
ChunkAccess chunk = chunkWrapper.getChunk();
|
||||||
if (chunk instanceof ProtoChunk)
|
if (chunk instanceof ProtoChunk protoChunk)
|
||||||
{
|
{
|
||||||
ProtoChunk protoChunk = ((ProtoChunk) chunk);
|
|
||||||
|
|
||||||
protoChunk.setLightEngine(region.getLightEngine());
|
protoChunk.setLightEngine(region.getLightEngine());
|
||||||
}
|
}
|
||||||
@@ -648,7 +731,19 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
|
|||||||
|
|
||||||
int maxSkyLight = this.serverlevel.getServerLevelWrapper().hasSkyLight() ? 15 : 0;
|
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.getStatus() != ChunkStatus.EMPTY)
|
||||||
|
{
|
||||||
|
iChunkWrapperList.add(chunkWrapper);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// light each chunk in the list
|
||||||
for (int i = 0; i < iChunkWrapperList.size(); i++)
|
for (int i = 0; i < iChunkWrapperList.size(); i++)
|
||||||
{
|
{
|
||||||
IChunkWrapper centerChunk = iChunkWrapperList.get(i);
|
IChunkWrapper centerChunk = iChunkWrapperList.get(i);
|
||||||
@@ -663,19 +758,19 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
|
|||||||
// if this isn't done everything else afterward may fail
|
// if this isn't done everything else afterward may fail
|
||||||
Heightmap.primeHeightmaps(((ChunkWrapper)centerChunk).getChunk(), ChunkStatus.FEATURES.heightmapsAfter());
|
Heightmap.primeHeightmaps(((ChunkWrapper)centerChunk).getChunk(), ChunkStatus.FEATURES.heightmapsAfter());
|
||||||
|
|
||||||
// populate the lighting
|
// pre-generated chunks should have lighting but new ones won't
|
||||||
|
if (!centerChunk.isLightCorrect())
|
||||||
|
{
|
||||||
DhLightingEngine.INSTANCE.lightChunk(centerChunk, iChunkWrapperList, maxSkyLight);
|
DhLightingEngine.INSTANCE.lightChunk(centerChunk, iChunkWrapperList, maxSkyLight);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
genEvent.refreshTimeout();
|
genEvent.refreshTimeout();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
private static <T> ArrayGridList<T> GetCutoutFrom(ArrayGridList<T> total, int border) { return new ArrayGridList<>(total, border, total.gridSize - border); }
|
||||||
|
private static <T> ArrayGridList<T> GetCutoutFrom(ArrayGridList<T> total, EDhApiWorldGenerationStep step) { return GetCutoutFrom(total, MaxBorderNeeded - BorderNeeded.get(step)); }
|
||||||
|
|
||||||
public interface EmptyChunkGenerator
|
|
||||||
{
|
|
||||||
ChunkAccess generate(int x, int z);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getEventCount() { return this.generationEventList.size(); }
|
public int getEventCount() { return this.generationEventList.size(); }
|
||||||
@@ -724,6 +819,12 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
|
|||||||
return genEvent.future;
|
return genEvent.future;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//================//
|
||||||
|
// helper methods //
|
||||||
|
//================//
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called before code that may run for an extended period of time. <br>
|
* Called before code that may run for an extended period of time. <br>
|
||||||
* This is necessary to allow canceling world gen since waiting
|
* This is necessary to allow canceling world gen since waiting
|
||||||
@@ -737,4 +838,16 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//================//
|
||||||
|
// helper classes //
|
||||||
|
//================//
|
||||||
|
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface IEmptyChunkGeneratorFunc
|
||||||
|
{
|
||||||
|
ChunkAccess generate(int x, int z);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
+2
-4
@@ -26,13 +26,11 @@ import java.util.concurrent.TimeUnit;
|
|||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
import com.seibel.distanthorizons.api.enums.worldGeneration.EDhApiWorldGenerationStep;
|
import com.seibel.distanthorizons.api.enums.worldGeneration.EDhApiWorldGenerationStep;
|
||||||
import com.seibel.distanthorizons.core.generation.WorldGenerationQueue;
|
|
||||||
import com.seibel.distanthorizons.core.util.ThreadUtil;
|
|
||||||
import com.seibel.distanthorizons.core.util.objects.UncheckedInterruptedException;
|
import com.seibel.distanthorizons.core.util.objects.UncheckedInterruptedException;
|
||||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||||
import com.seibel.distanthorizons.core.pos.DhChunkPos;
|
import com.seibel.distanthorizons.core.pos.DhChunkPos;
|
||||||
import com.seibel.distanthorizons.core.util.objects.EventTimer;
|
import com.seibel.distanthorizons.core.util.objects.EventTimer;
|
||||||
import com.seibel.distanthorizons.core.util.threading.ThreadPools;
|
import com.seibel.distanthorizons.core.util.threading.ThreadPoolUtil;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.chunk.IChunkWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.chunk.IChunkWrapper;
|
||||||
|
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
@@ -123,7 +121,7 @@ public final class GenerationEvent
|
|||||||
public boolean terminate()
|
public boolean terminate()
|
||||||
{
|
{
|
||||||
LOGGER.info("======================DUMPING ALL THREADS FOR WORLD GEN=======================");
|
LOGGER.info("======================DUMPING ALL THREADS FOR WORLD GEN=======================");
|
||||||
ThreadPools.WORLD_GEN_THREAD_FACTORY.dumpAllThreadStacks();
|
ThreadPoolUtil.WORLD_GEN_THREAD_FACTORY.dumpAllThreadStacks();
|
||||||
this.future.cancel(true);
|
this.future.cancel(true);
|
||||||
return this.future.isCancelled();
|
return this.future.isCancelled();
|
||||||
}
|
}
|
||||||
|
|||||||
+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.Biome;
|
||||||
import net.minecraft.world.level.biome.BiomeManager;
|
import net.minecraft.world.level.biome.BiomeManager;
|
||||||
import net.minecraft.world.level.chunk.ChunkGenerator;
|
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;
|
import net.minecraft.world.level.chunk.storage.ChunkScanAccess;
|
||||||
#endif
|
#endif
|
||||||
import net.minecraft.world.level.levelgen.WorldGenSettings;
|
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;
|
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureManager;
|
||||||
#else
|
#else
|
||||||
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplateManager;
|
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplateManager;
|
||||||
import net.minecraft.world.level.levelgen.RandomState;
|
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.world.level.levelgen.WorldOptions;
|
||||||
import net.minecraft.core.registries.Registries;
|
import net.minecraft.core.registries.Registries;
|
||||||
#endif
|
#endif
|
||||||
@@ -50,13 +50,13 @@ import net.minecraft.world.level.storage.WorldData;
|
|||||||
public final class GlobalParameters
|
public final class GlobalParameters
|
||||||
{
|
{
|
||||||
public final ChunkGenerator generator;
|
public final ChunkGenerator generator;
|
||||||
#if PRE_MC_1_19_2
|
#if MC_VER < MC_1_19_2
|
||||||
public final StructureManager structures;
|
public final StructureManager structures;
|
||||||
#else
|
#else
|
||||||
public final StructureTemplateManager structures;
|
public final StructureTemplateManager structures;
|
||||||
public final RandomState randomState;
|
public final RandomState randomState;
|
||||||
#endif
|
#endif
|
||||||
#if PRE_MC_1_19_4
|
#if MC_VER < MC_1_19_4
|
||||||
public final WorldGenSettings worldGenSettings;
|
public final WorldGenSettings worldGenSettings;
|
||||||
#else
|
#else
|
||||||
public final WorldOptions worldOptions;
|
public final WorldOptions worldOptions;
|
||||||
@@ -67,7 +67,7 @@ public final class GlobalParameters
|
|||||||
public final RegistryAccess registry;
|
public final RegistryAccess registry;
|
||||||
public final long worldSeed;
|
public final long worldSeed;
|
||||||
public final DataFixer fixerUpper;
|
public final DataFixer fixerUpper;
|
||||||
#if POST_MC_1_18_2
|
#if MC_VER >= MC_1_18_2
|
||||||
public final BiomeManager biomeManager;
|
public final BiomeManager biomeManager;
|
||||||
public final ChunkScanAccess chunkScanner; // FIXME: Figure out if this is actually needed
|
public final ChunkScanAccess chunkScanner; // FIXME: Figure out if this is actually needed
|
||||||
#endif
|
#endif
|
||||||
@@ -81,7 +81,7 @@ public final class GlobalParameters
|
|||||||
WorldData worldData = server.getWorldData();
|
WorldData worldData = server.getWorldData();
|
||||||
registry = server.registryAccess();
|
registry = server.registryAccess();
|
||||||
|
|
||||||
#if PRE_MC_1_19_4
|
#if MC_VER < MC_1_19_4
|
||||||
worldGenSettings = worldData.worldGenSettings();
|
worldGenSettings = worldData.worldGenSettings();
|
||||||
biomes = registry.registryOrThrow(Registry.BIOME_REGISTRY);
|
biomes = registry.registryOrThrow(Registry.BIOME_REGISTRY);
|
||||||
worldSeed = worldGenSettings.seed();
|
worldSeed = worldGenSettings.seed();
|
||||||
@@ -90,14 +90,14 @@ public final class GlobalParameters
|
|||||||
biomes = registry.registryOrThrow(Registries.BIOME);
|
biomes = registry.registryOrThrow(Registries.BIOME);
|
||||||
worldSeed = worldOptions.seed();
|
worldSeed = worldOptions.seed();
|
||||||
#endif
|
#endif
|
||||||
#if POST_MC_1_18_2
|
#if MC_VER >= MC_1_18_2
|
||||||
biomeManager = new BiomeManager(level, BiomeManager.obfuscateSeed(worldSeed));
|
biomeManager = new BiomeManager(level, BiomeManager.obfuscateSeed(worldSeed));
|
||||||
chunkScanner = level.getChunkSource().chunkScanner();
|
chunkScanner = level.getChunkSource().chunkScanner();
|
||||||
#endif
|
#endif
|
||||||
structures = server.getStructureManager();
|
structures = server.getStructureManager();
|
||||||
generator = level.getChunkSource().getGenerator();
|
generator = level.getChunkSource().getGenerator();
|
||||||
fixerUpper = server.getFixerUpper();
|
fixerUpper = server.getFixerUpper();
|
||||||
#if POST_MC_1_19_2
|
#if MC_VER >= MC_1_19_2
|
||||||
randomState = level.getChunkSource().randomState();
|
randomState = level.getChunkSource().randomState();
|
||||||
#endif
|
#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.server.level.ServerLevel;
|
||||||
import net.minecraft.world.level.WorldGenLevel;
|
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;
|
import net.minecraft.world.level.levelgen.structure.StructureCheck;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -35,7 +35,7 @@ public final class ThreadedParameters
|
|||||||
|
|
||||||
final ServerLevel level;
|
final ServerLevel level;
|
||||||
public WorldGenStructFeatManager structFeat = null;
|
public WorldGenStructFeatManager structFeat = null;
|
||||||
#if POST_MC_1_18_2
|
#if MC_VER >= MC_1_18_2
|
||||||
public StructureCheck structCheck;
|
public StructureCheck structCheck;
|
||||||
#endif
|
#endif
|
||||||
boolean isValid = true;
|
boolean isValid = true;
|
||||||
@@ -63,9 +63,9 @@ public final class ThreadedParameters
|
|||||||
previousGlobalParameters = param;
|
previousGlobalParameters = param;
|
||||||
|
|
||||||
this.level = param.level;
|
this.level = param.level;
|
||||||
#if PRE_MC_1_18_2
|
#if MC_VER < MC_1_18_2
|
||||||
this.structFeat = new WorldGenStructFeatManager(param.worldGenSettings, level);
|
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);
|
this.structCheck = this.createStructureCheck(param);
|
||||||
#else
|
#else
|
||||||
this.structCheck = new StructureCheck(param.chunkScanner, param.registry, param.structures,
|
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)
|
public void makeStructFeat(WorldGenLevel genLevel, GlobalParameters param)
|
||||||
{
|
{
|
||||||
#if PRE_MC_1_19_4
|
#if MC_VER < MC_1_19_4
|
||||||
structFeat = new WorldGenStructFeatManager(param.worldGenSettings, genLevel #if POST_MC_1_18_2 , structCheck #endif );
|
structFeat = new WorldGenStructFeatManager(param.worldGenSettings, genLevel #if MC_VER >= MC_1_18_2 , structCheck #endif );
|
||||||
#else
|
#else
|
||||||
structFeat = new WorldGenStructFeatManager(param.worldOptions, genLevel, structCheck);
|
structFeat = new WorldGenStructFeatManager(param.worldOptions, genLevel, structCheck);
|
||||||
#endif
|
#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()
|
public void recreateStructureCheck()
|
||||||
{
|
{
|
||||||
if (previousGlobalParameters != null)
|
if (previousGlobalParameters != null)
|
||||||
|
|||||||
+358
-148
@@ -22,9 +22,14 @@ package com.seibel.distanthorizons.common.wrappers.worldGeneration.mimicObject;
|
|||||||
import com.google.common.collect.Maps;
|
import com.google.common.collect.Maps;
|
||||||
import com.mojang.serialization.Codec;
|
import com.mojang.serialization.Codec;
|
||||||
import com.mojang.serialization.Dynamic;
|
import com.mojang.serialization.Dynamic;
|
||||||
|
import com.seibel.distanthorizons.common.wrappers.chunk.ChunkWrapper;
|
||||||
import com.seibel.distanthorizons.common.wrappers.worldGeneration.BatchGenerationEnvironment;
|
import com.seibel.distanthorizons.common.wrappers.worldGeneration.BatchGenerationEnvironment;
|
||||||
|
|
||||||
import com.seibel.distanthorizons.core.logging.ConfigBasedLogger;
|
import com.seibel.distanthorizons.core.logging.ConfigBasedLogger;
|
||||||
|
import com.seibel.distanthorizons.core.util.LodUtil;
|
||||||
|
import com.seibel.distanthorizons.core.wrapperInterfaces.block.IBlockStateWrapper;
|
||||||
|
import com.seibel.distanthorizons.core.wrapperInterfaces.chunk.ChunkLightStorage;
|
||||||
|
import com.seibel.distanthorizons.core.wrapperInterfaces.chunk.IChunkWrapper;
|
||||||
import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
|
import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
|
||||||
import it.unimi.dsi.fastutil.longs.LongSet;
|
import it.unimi.dsi.fastutil.longs.LongSet;
|
||||||
|
|
||||||
@@ -37,13 +42,14 @@ import java.util.Objects;
|
|||||||
|
|
||||||
import net.minecraft.core.Registry;
|
import net.minecraft.core.Registry;
|
||||||
import net.minecraft.core.SectionPos;
|
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.BuiltInRegistries;
|
||||||
import net.minecraft.core.registries.Registries;
|
import net.minecraft.core.registries.Registries;
|
||||||
#endif
|
#endif
|
||||||
import net.minecraft.nbt.CompoundTag;
|
import net.minecraft.nbt.CompoundTag;
|
||||||
import net.minecraft.nbt.ListTag;
|
import net.minecraft.nbt.ListTag;
|
||||||
import net.minecraft.nbt.NbtOps;
|
import net.minecraft.nbt.NbtOps;
|
||||||
|
import net.minecraft.nbt.Tag;
|
||||||
import net.minecraft.resources.ResourceKey;
|
import net.minecraft.resources.ResourceKey;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
import net.minecraft.world.level.*;
|
import net.minecraft.world.level.*;
|
||||||
@@ -55,35 +61,45 @@ import net.minecraft.world.level.block.state.BlockState;
|
|||||||
import net.minecraft.world.level.chunk.*;
|
import net.minecraft.world.level.chunk.*;
|
||||||
import net.minecraft.world.level.chunk.storage.ChunkSerializer;
|
import net.minecraft.world.level.chunk.storage.ChunkSerializer;
|
||||||
import net.minecraft.world.level.levelgen.Heightmap;
|
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;
|
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;
|
import net.minecraft.world.level.levelgen.feature.StructureFeature;
|
||||||
#endif
|
#endif
|
||||||
import net.minecraft.world.level.levelgen.structure.StructureStart;
|
import net.minecraft.world.level.levelgen.structure.StructureStart;
|
||||||
import net.minecraft.world.level.levelgen.structure.pieces.StructurePieceSerializationContext;
|
import net.minecraft.world.level.levelgen.structure.pieces.StructurePieceSerializationContext;
|
||||||
import net.minecraft.world.ticks.LevelChunkTicks;
|
import net.minecraft.world.ticks.LevelChunkTicks;
|
||||||
#endif
|
#endif
|
||||||
#if POST_MC_1_18_2
|
#if MC_VER >= MC_1_18_2
|
||||||
import net.minecraft.core.Holder;
|
import net.minecraft.core.Holder;
|
||||||
import net.minecraft.core.RegistryAccess;
|
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;
|
import net.minecraft.world.level.levelgen.feature.ConfiguredStructureFeature;
|
||||||
#endif
|
#endif
|
||||||
#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;
|
import net.minecraft.world.level.material.Fluids;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if MC_VER == MC_1_20_6
|
||||||
|
import net.minecraft.world.level.chunk.status.ChunkStatus;
|
||||||
|
import net.minecraft.world.level.chunk.status.ChunkType;
|
||||||
|
#elif MC_VER == MC_1_21
|
||||||
|
import net.minecraft.world.level.chunk.status.ChunkStatus;
|
||||||
|
import net.minecraft.world.level.chunk.status.ChunkType;
|
||||||
|
#endif
|
||||||
|
|
||||||
import net.minecraft.world.level.material.Fluid;
|
import net.minecraft.world.level.material.Fluid;
|
||||||
|
|
||||||
|
|
||||||
public class ChunkLoader
|
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());
|
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());
|
private static final Codec<PalettedContainer<BlockState>> BLOCK_STATE_CODEC = PalettedContainer.codec(Block.BLOCK_STATE_REGISTRY, BlockState.CODEC, PalettedContainer.Strategy.SECTION_STATES, Blocks.AIR.defaultBlockState());
|
||||||
#endif
|
#endif
|
||||||
private static final String TAG_UPGRADE_DATA = "UpgradeData";
|
private static final String TAG_UPGRADE_DATA = "UpgradeData";
|
||||||
@@ -93,137 +109,17 @@ public class ChunkLoader
|
|||||||
private static final String FLUID_TICKS_TAG_PRE18 = "LiquidTicks";
|
private static final String FLUID_TICKS_TAG_PRE18 = "LiquidTicks";
|
||||||
private static final ConfigBasedLogger LOGGER = BatchGenerationEnvironment.LOAD_LOGGER;
|
private static final ConfigBasedLogger LOGGER = BatchGenerationEnvironment.LOAD_LOGGER;
|
||||||
|
|
||||||
#if POST_MC_1_18_2
|
private static boolean lightingSectionErrorLogged = false;
|
||||||
private static BlendingData readBlendingData(CompoundTag chunkData)
|
|
||||||
{
|
|
||||||
BlendingData blendingData = null;
|
|
||||||
if (chunkData.contains("blending_data", 10))
|
|
||||||
{
|
|
||||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
|
||||||
Dynamic<CompoundTag> blendingDataTag = new Dynamic(NbtOps.INSTANCE, chunkData.getCompound("blending_data"));
|
|
||||||
blendingData = BlendingData.CODEC.parse(blendingDataTag).resultOrPartial(LOGGER::error).orElse(null);
|
|
||||||
}
|
|
||||||
return blendingData;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
private static LevelChunkSection[] readSections(LevelAccessor level, ChunkPos chunkPos, CompoundTag chunkData)
|
|
||||||
{
|
|
||||||
#if POST_MC_1_18_2
|
|
||||||
#if PRE_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
|
|
||||||
Codec<PalettedContainer<Biome>> biomeCodec = PalettedContainer.codec(
|
|
||||||
biomes, biomes.byNameCodec(), PalettedContainer.Strategy.SECTION_BIOMES, biomes.getOrThrow(Biomes.PLAINS));
|
|
||||||
#elif PRE_MC_1_19_2
|
|
||||||
Codec<PalettedContainer<Holder<Biome>>> biomeCodec = PalettedContainer.codec(
|
|
||||||
biomes.asHolderIdMap(), biomes.holderByNameCodec(), PalettedContainer.Strategy.SECTION_BIOMES, biomes.getHolderOrThrow(Biomes.PLAINS));
|
|
||||||
#else
|
|
||||||
Codec<PalettedContainer<Holder<Biome>>> biomeCodec = PalettedContainer.codecRW(
|
|
||||||
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
|
|
||||||
LevelChunkSection[] chunkSections = new LevelChunkSection[i];
|
|
||||||
|
|
||||||
boolean isLightOn = chunkData.getBoolean("isLightOn");
|
|
||||||
boolean hasSkyLight = level.dimensionType().hasSkyLight();
|
|
||||||
ListTag tagSections = chunkData.getList("Sections", 10);
|
|
||||||
if (tagSections.isEmpty()) tagSections = chunkData.getList("sections", 10);
|
|
||||||
|
|
||||||
for (int j = 0; j < tagSections.size(); ++j)
|
//============//
|
||||||
{
|
// read chunk //
|
||||||
CompoundTag tagSection = tagSections.getCompound(j);
|
//============//
|
||||||
int sectionYPos = tagSection.getByte("Y");
|
|
||||||
|
|
||||||
#if PRE_MC_1_18_2
|
|
||||||
if (tagSection.contains("Palette", 9) && tagSection.contains("BlockStates", 12))
|
|
||||||
{
|
|
||||||
LevelChunkSection levelChunkSection = new LevelChunkSection(sectionYPos << 4);
|
|
||||||
levelChunkSection.getStates().read(tagSection.getList("Palette", 10),
|
|
||||||
tagSection.getLongArray("BlockStates"));
|
|
||||||
levelChunkSection.recalcBlockCounts();
|
|
||||||
if (!levelChunkSection.isEmpty())
|
|
||||||
chunkSections[#if PRE_MC_1_17_1 sectionYPos #else level.getSectionIndexFromSectionY(sectionYPos) #endif ]
|
|
||||||
= levelChunkSection;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
int sectionId = level.getSectionIndexFromSectionY(sectionYPos);
|
|
||||||
if (sectionId >= 0 && sectionId < chunkSections.length)
|
|
||||||
{
|
|
||||||
PalettedContainer<BlockState> blockStateContainer;
|
|
||||||
#if PRE_MC_1_18_2
|
|
||||||
PalettedContainer<Biome> biomeContainer;
|
|
||||||
#else
|
|
||||||
PalettedContainer<Holder<Biome>> biomeContainer;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
blockStateContainer = tagSection.contains("block_states", 10)
|
|
||||||
? 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
|
|
||||||
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);
|
|
||||||
#else
|
|
||||||
biomeContainer = tagSection.contains("biomes", 10)
|
|
||||||
? 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
|
|
||||||
chunkSections[sectionId] = new LevelChunkSection(sectionYPos, blockStateContainer, biomeContainer);
|
|
||||||
#else
|
|
||||||
chunkSections[sectionId] = new LevelChunkSection(blockStateContainer, biomeContainer);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}
|
|
||||||
return chunkSections;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void readHeightmaps(LevelChunk chunk, CompoundTag chunkData)
|
|
||||||
{
|
|
||||||
CompoundTag tagHeightmaps = chunkData.getCompound("Heightmaps");
|
|
||||||
for (Heightmap.Types type : ChunkStatus.FULL.heightmapsAfter())
|
|
||||||
{
|
|
||||||
String heightmap = type.getSerializationKey();
|
|
||||||
if (tagHeightmaps.contains(heightmap, 12))
|
|
||||||
chunk.setHeightmap(type, tagHeightmaps.getLongArray(heightmap));
|
|
||||||
}
|
|
||||||
Heightmap.primeHeightmaps(chunk, ChunkStatus.FULL.heightmapsAfter());
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void readPostPocessings(LevelChunk chunk, CompoundTag chunkData)
|
|
||||||
{
|
|
||||||
ListTag tagPostProcessings = chunkData.getList("PostProcessing", 9);
|
|
||||||
for (int n = 0; n < tagPostProcessings.size(); ++n)
|
|
||||||
{
|
|
||||||
ListTag listTag3 = tagPostProcessings.getList(n);
|
|
||||||
for (int o = 0; o < listTag3.size(); ++o)
|
|
||||||
{
|
|
||||||
chunk.addPackedPostProcess(listTag3.getShort(o), n);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ChunkStatus.ChunkType readChunkType(CompoundTag tagLevel)
|
|
||||||
{
|
|
||||||
ChunkStatus chunkStatus = ChunkStatus.byName(tagLevel.getString("Status"));
|
|
||||||
if (chunkStatus != null)
|
|
||||||
{
|
|
||||||
return chunkStatus.getChunkType();
|
|
||||||
}
|
|
||||||
return ChunkStatus.ChunkType.PROTOCHUNK;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static LevelChunk read(WorldGenLevel level, ChunkPos chunkPos, CompoundTag chunkData)
|
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");
|
CompoundTag tagLevel = chunkData.getCompound("Level");
|
||||||
#else
|
#else
|
||||||
CompoundTag tagLevel = chunkData;
|
CompoundTag tagLevel = chunkData;
|
||||||
@@ -232,50 +128,82 @@ public class ChunkLoader
|
|||||||
ChunkPos actualPos = new ChunkPos(tagLevel.getInt("xPos"), tagLevel.getInt("zPos"));
|
ChunkPos actualPos = new ChunkPos(tagLevel.getInt("xPos"), tagLevel.getInt("zPos"));
|
||||||
if (!Objects.equals(chunkPos, actualPos))
|
if (!Objects.equals(chunkPos, actualPos))
|
||||||
{
|
{
|
||||||
LOGGER.error("Chunk file at {} is in the wrong location; Ignoring. (Expected {}, got {})", chunkPos, chunkPos, actualPos);
|
#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;
|
return null;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ChunkStatus.ChunkType chunkType = readChunkType(tagLevel);
|
#if MC_VER < MC_1_20_6
|
||||||
#if PRE_MC_1_18_2
|
ChunkStatus.ChunkType chunkType;
|
||||||
|
#else
|
||||||
|
ChunkType chunkType;
|
||||||
|
#endif
|
||||||
|
chunkType = readChunkType(tagLevel);
|
||||||
|
|
||||||
|
#if MC_VER < MC_1_18_2
|
||||||
if (chunkType != ChunkStatus.ChunkType.LEVELCHUNK)
|
if (chunkType != ChunkStatus.ChunkType.LEVELCHUNK)
|
||||||
return null;
|
return null;
|
||||||
#else
|
#else
|
||||||
|
|
||||||
BlendingData blendingData = readBlendingData(tagLevel);
|
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()))
|
if (chunkType == ChunkStatus.ChunkType.PROTOCHUNK && (blendingData == null || !blendingData.oldNoise()))
|
||||||
return null;
|
return null;
|
||||||
#else
|
#else
|
||||||
if (chunkType == ChunkStatus.ChunkType.PROTOCHUNK && blendingData == null)
|
if (chunkType == #if MC_VER < MC_1_20_6 ChunkStatus.ChunkType.PROTOCHUNK #else ChunkType.PROTOCHUNK #endif && blendingData == null)
|
||||||
return null;
|
return null;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
long inhabitedTime = tagLevel.getLong("InhabitedTime");
|
long inhabitedTime = tagLevel.getLong("InhabitedTime");
|
||||||
|
|
||||||
//================== Read params for making the LevelChunk ==================
|
//================== Read params for making the LevelChunk ==================
|
||||||
UpgradeData upgradeData = tagLevel.contains(TAG_UPGRADE_DATA, 10)
|
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;
|
: UpgradeData.EMPTY;
|
||||||
|
|
||||||
boolean isLightOn = tagLevel.getBoolean("isLightOn");
|
boolean isLightOn = tagLevel.getBoolean("isLightOn");
|
||||||
#if PRE_MC_1_18_2
|
#if MC_VER < MC_1_18_2
|
||||||
ChunkBiomeContainer chunkBiomeContainer = new ChunkBiomeContainer(
|
ChunkBiomeContainer chunkBiomeContainer = new ChunkBiomeContainer(
|
||||||
level.getLevel().registryAccess().registryOrThrow(Registry.BIOME_REGISTRY)#if 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(),
|
chunkPos, level.getLevel().getChunkSource().getGenerator().getBiomeSource(),
|
||||||
tagLevel.contains("Biomes", 11) ? tagLevel.getIntArray("Biomes") : null);
|
tagLevel.contains("Biomes", 11) ? tagLevel.getIntArray("Biomes") : null);
|
||||||
|
|
||||||
TickList<Block> blockTicks = tagLevel.contains(BLOCK_TICKS_TAG_PRE18, 9)
|
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)
|
? 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,
|
: 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)
|
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)
|
? 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,
|
: 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
|
#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),
|
LevelChunkTicks<Block> blockTicks = LevelChunkTicks.load(tagLevel.getList(BLOCK_TICKS_TAG_18, 10),
|
||||||
string -> Registry.BLOCK.getOptional(ResourceLocation.tryParse(string)), chunkPos);
|
string -> Registry.BLOCK.getOptional(ResourceLocation.tryParse(string)), chunkPos);
|
||||||
LevelChunkTicks<Fluid> fluidTicks = LevelChunkTicks.load(tagLevel.getList(FLUID_TICKS_TAG_18, 10),
|
LevelChunkTicks<Fluid> fluidTicks = LevelChunkTicks.load(tagLevel.getList(FLUID_TICKS_TAG_18, 10),
|
||||||
@@ -291,7 +219,7 @@ public class ChunkLoader
|
|||||||
LevelChunkSection[] levelChunkSections = readSections(level, chunkPos, tagLevel);
|
LevelChunkSection[] levelChunkSections = readSections(level, chunkPos, tagLevel);
|
||||||
|
|
||||||
// ====================== Make the chunk =========================
|
// ====================== 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,
|
LevelChunk chunk = new LevelChunk((Level) level.getLevel(), chunkPos, chunkBiomeContainer, upgradeData, blockTicks,
|
||||||
fluidTicks, inhabitedTime, levelChunkSections, null);
|
fluidTicks, inhabitedTime, levelChunkSections, null);
|
||||||
#else
|
#else
|
||||||
@@ -305,10 +233,292 @@ public class ChunkLoader
|
|||||||
readPostPocessings(chunk, chunkData);
|
readPostPocessings(chunk, chunkData);
|
||||||
return chunk;
|
return chunk;
|
||||||
}
|
}
|
||||||
|
private static LevelChunkSection[] readSections(LevelAccessor level, ChunkPos chunkPos, CompoundTag chunkData)
|
||||||
private static void logErrors(ChunkPos chunkPos, int i, String string)
|
|
||||||
{
|
{
|
||||||
LOGGER.error("Distant Horizons: Recoverable errors when loading section [" + chunkPos.x + ", " + i + ", " + chunkPos.z + "]: " + string);
|
#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 MC_VER < MC_1_18_2
|
||||||
|
Codec<PalettedContainer<Biome>> biomeCodec = PalettedContainer.codec(
|
||||||
|
biomes, biomes.byNameCodec(), PalettedContainer.Strategy.SECTION_BIOMES, biomes.getOrThrow(Biomes.PLAINS));
|
||||||
|
#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
|
||||||
|
Codec<PalettedContainer<Holder<Biome>>> biomeCodec = PalettedContainer.codecRW(
|
||||||
|
biomes.asHolderIdMap(), biomes.holderByNameCodec(), PalettedContainer.Strategy.SECTION_BIOMES, biomes.getHolderOrThrow(Biomes.PLAINS));
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
int sectionYIndex = #if MC_VER < MC_1_17_1 16; #else level.getSectionsCount(); #endif
|
||||||
|
LevelChunkSection[] chunkSections = new LevelChunkSection[sectionYIndex];
|
||||||
|
|
||||||
|
boolean isLightOn = chunkData.getBoolean("isLightOn");
|
||||||
|
boolean hasSkyLight = level.dimensionType().hasSkyLight();
|
||||||
|
ListTag tagSections = chunkData.getList("Sections", 10);
|
||||||
|
if (tagSections.isEmpty()) tagSections = chunkData.getList("sections", 10);
|
||||||
|
|
||||||
|
for (int j = 0; j < tagSections.size(); ++j)
|
||||||
|
{
|
||||||
|
CompoundTag tagSection = tagSections.getCompound(j);
|
||||||
|
int sectionYPos = tagSection.getByte("Y");
|
||||||
|
|
||||||
|
#if MC_VER < MC_1_18_2
|
||||||
|
if (tagSection.contains("Palette", 9) && tagSection.contains("BlockStates", 12))
|
||||||
|
{
|
||||||
|
LevelChunkSection levelChunkSection = new LevelChunkSection(sectionYPos << 4);
|
||||||
|
levelChunkSection.getStates().read(tagSection.getList("Palette", 10),
|
||||||
|
tagSection.getLongArray("BlockStates"));
|
||||||
|
levelChunkSection.recalcBlockCounts();
|
||||||
|
if (!levelChunkSection.isEmpty())
|
||||||
|
chunkSections[#if MC_VER < MC_1_17_1 sectionYPos #else level.getSectionIndexFromSectionY(sectionYPos) #endif ]
|
||||||
|
= levelChunkSection;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
int sectionId = level.getSectionIndexFromSectionY(sectionYPos);
|
||||||
|
if (sectionId >= 0 && sectionId < chunkSections.length)
|
||||||
|
{
|
||||||
|
PalettedContainer<BlockState> blockStateContainer;
|
||||||
|
#if MC_VER < MC_1_18_2
|
||||||
|
PalettedContainer<Biome> biomeContainer;
|
||||||
|
#else
|
||||||
|
PalettedContainer<Holder<Biome>> biomeContainer;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
blockStateContainer = tagSection.contains("block_states", 10)
|
||||||
|
? BLOCK_STATE_CODEC.parse(NbtOps.INSTANCE, tagSection.getCompound("block_states")).promotePartial(string -> logBlockDeserializationWarning(chunkPos, sectionYPos, string))
|
||||||
|
#if MC_VER < MC_1_20_6
|
||||||
|
.getOrThrow(false, LOGGER::error)
|
||||||
|
#else
|
||||||
|
.getOrThrow((message) -> (RuntimeException) LOGGER.errorAndThrow(message, null))
|
||||||
|
#endif
|
||||||
|
: new PalettedContainer<>(Block.BLOCK_STATE_REGISTRY, Blocks.AIR.defaultBlockState(), PalettedContainer.Strategy.SECTION_STATES);
|
||||||
|
|
||||||
|
#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);
|
||||||
|
#else
|
||||||
|
|
||||||
|
biomeContainer = tagSection.contains("biomes", 10)
|
||||||
|
? biomeCodec.parse(NbtOps.INSTANCE, tagSection.getCompound("biomes")).promotePartial(string -> logBiomeDeserializationWarning(chunkPos, sectionYIndex, (String) string))
|
||||||
|
#if MC_VER < MC_1_20_6
|
||||||
|
.getOrThrow(false, LOGGER::error)
|
||||||
|
#else
|
||||||
|
.getOrThrow((message) -> (RuntimeException) LOGGER.errorAndThrow(message, null))
|
||||||
|
#endif
|
||||||
|
: new PalettedContainer<>(biomes.asHolderIdMap(), biomes.getHolderOrThrow(Biomes.PLAINS), PalettedContainer.Strategy.SECTION_BIOMES);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if MC_VER < MC_1_20_1
|
||||||
|
chunkSections[sectionId] = new LevelChunkSection(sectionYPos, blockStateContainer, biomeContainer);
|
||||||
|
#else
|
||||||
|
chunkSections[sectionId] = new LevelChunkSection(blockStateContainer, biomeContainer);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
return chunkSections;
|
||||||
|
}
|
||||||
|
private static
|
||||||
|
#if MC_VER < MC_1_20_6 ChunkStatus.ChunkType
|
||||||
|
#elif MC_VER < MC_1_21 ChunkType
|
||||||
|
#else ChunkType #endif
|
||||||
|
readChunkType(CompoundTag tagLevel)
|
||||||
|
{
|
||||||
|
ChunkStatus chunkStatus = ChunkStatus.byName(tagLevel.getString("Status"));
|
||||||
|
if (chunkStatus != null)
|
||||||
|
{
|
||||||
|
return chunkStatus.getChunkType();
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
#if MC_VER <= MC_1_20_4 ChunkStatus.ChunkType.PROTOCHUNK;
|
||||||
|
#else ChunkType.PROTOCHUNK; #endif
|
||||||
|
}
|
||||||
|
private static void readHeightmaps(LevelChunk chunk, CompoundTag chunkData)
|
||||||
|
{
|
||||||
|
CompoundTag tagHeightmaps = chunkData.getCompound("Heightmaps");
|
||||||
|
for (Heightmap.Types type : ChunkStatus.FULL.heightmapsAfter())
|
||||||
|
{
|
||||||
|
String heightmap = type.getSerializationKey();
|
||||||
|
if (tagHeightmaps.contains(heightmap, 12))
|
||||||
|
chunk.setHeightmap(type, tagHeightmaps.getLongArray(heightmap));
|
||||||
|
}
|
||||||
|
Heightmap.primeHeightmaps(chunk, ChunkStatus.FULL.heightmapsAfter());
|
||||||
|
}
|
||||||
|
private static void readPostPocessings(LevelChunk chunk, CompoundTag chunkData)
|
||||||
|
{
|
||||||
|
ListTag tagPostProcessings = chunkData.getList("PostProcessing", 9);
|
||||||
|
for (int n = 0; n < tagPostProcessings.size(); ++n)
|
||||||
|
{
|
||||||
|
ListTag listTag3 = tagPostProcessings.getList(n);
|
||||||
|
for (int o = 0; o < listTag3.size(); ++o)
|
||||||
|
{
|
||||||
|
chunk.addPackedPostProcess(listTag3.getShort(o), n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#if MC_VER >= MC_1_18_2
|
||||||
|
private static BlendingData readBlendingData(CompoundTag chunkData)
|
||||||
|
{
|
||||||
|
BlendingData blendingData = null;
|
||||||
|
if (chunkData.contains("blending_data", 10))
|
||||||
|
{
|
||||||
|
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||||
|
Dynamic<CompoundTag> blendingDataTag = new Dynamic(NbtOps.INSTANCE, chunkData.getCompound("blending_data"));
|
||||||
|
blendingData = BlendingData.CODEC.parse(blendingDataTag).resultOrPartial(LOGGER::error).orElse(null);
|
||||||
|
}
|
||||||
|
return blendingData;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//=====================//
|
||||||
|
// read chunk lighting //
|
||||||
|
//=====================//
|
||||||
|
|
||||||
|
/**
|
||||||
|
* https://minecraft.wiki/w/Chunk_format
|
||||||
|
*/
|
||||||
|
public static CombinedChunkLightStorage readLight(ChunkAccess chunk, CompoundTag chunkData)
|
||||||
|
{
|
||||||
|
#if MC_VER <= MC_1_17_1
|
||||||
|
// MC 1.16 and 1.17 doesn't have the necessary NBT info
|
||||||
|
return null;
|
||||||
|
#else
|
||||||
|
|
||||||
|
CombinedChunkLightStorage combinedStorage = new CombinedChunkLightStorage(ChunkWrapper.getMinBuildHeight(chunk), ChunkWrapper.getMaxBuildHeight(chunk));
|
||||||
|
ChunkLightStorage blockLightStorage = combinedStorage.blockLightStorage;
|
||||||
|
ChunkLightStorage skyLightStorage = combinedStorage.skyLightStorage;
|
||||||
|
|
||||||
|
boolean foundSkyLight = false;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//===================//
|
||||||
|
// get NBT tags info //
|
||||||
|
//===================//
|
||||||
|
|
||||||
|
Tag chunkSectionTags = chunkData.get("sections");
|
||||||
|
if (chunkSectionTags == null)
|
||||||
|
{
|
||||||
|
if (!lightingSectionErrorLogged)
|
||||||
|
{
|
||||||
|
lightingSectionErrorLogged = true;
|
||||||
|
LOGGER.error("No sections found for chunk at pos ["+chunk.getPos()+"] chunk data may be out of date.");
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
else if (!(chunkSectionTags instanceof ListTag))
|
||||||
|
{
|
||||||
|
if (!lightingSectionErrorLogged)
|
||||||
|
{
|
||||||
|
lightingSectionErrorLogged = true;
|
||||||
|
LOGGER.error("Chunk section tag list have unexpected type ["+chunkSectionTags.getClass().getName()+"], expected ["+ListTag.class.getName()+"].");
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
ListTag chunkSectionListTag = (ListTag) chunkSectionTags;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//===================//
|
||||||
|
// get lighting info //
|
||||||
|
//===================//
|
||||||
|
|
||||||
|
for (int sectionIndex = 0; sectionIndex < chunkSectionListTag.size(); sectionIndex++)
|
||||||
|
{
|
||||||
|
Tag chunkSectionTag = chunkSectionListTag.get(sectionIndex);
|
||||||
|
if (!(chunkSectionTag instanceof CompoundTag chunkSectionCompoundTag))
|
||||||
|
{
|
||||||
|
if (!lightingSectionErrorLogged)
|
||||||
|
{
|
||||||
|
lightingSectionErrorLogged = true;
|
||||||
|
LOGGER.error("Chunk section tag has an unexpected type ["+chunkSectionTag.getClass().getName()+"], expected ["+CompoundTag.class.getName()+"].");
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// if null all lights = 0
|
||||||
|
byte[] blockLightNibbleArray = chunkSectionCompoundTag.getByteArray("BlockLight");
|
||||||
|
byte[] skyLightNibbleArray = chunkSectionCompoundTag.getByteArray("SkyLight");
|
||||||
|
|
||||||
|
// if any sky light was found then all lights above will be max brightness
|
||||||
|
if (skyLightNibbleArray.length != 0)
|
||||||
|
{
|
||||||
|
foundSkyLight = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int relX = 0; relX < LodUtil.CHUNK_WIDTH; relX++)
|
||||||
|
{
|
||||||
|
for (int relZ = 0; relZ < LodUtil.CHUNK_WIDTH; relZ++)
|
||||||
|
{
|
||||||
|
// chunk sections are also 16 blocks tall
|
||||||
|
for (int relY = 0; relY < LodUtil.CHUNK_WIDTH; relY++)
|
||||||
|
{
|
||||||
|
int blockPosIndex = relY*16*16 + relZ*16 + relX;
|
||||||
|
byte blockLight = (blockLightNibbleArray.length == 0) ? 0 : getNibbleAtIndex(blockLightNibbleArray, blockPosIndex);
|
||||||
|
byte skyLight = (skyLightNibbleArray.length == 0) ? 0 : getNibbleAtIndex(skyLightNibbleArray, blockPosIndex);
|
||||||
|
if (skyLightNibbleArray.length == 0 && foundSkyLight)
|
||||||
|
{
|
||||||
|
skyLight = LodUtil.MAX_MC_LIGHT;
|
||||||
|
}
|
||||||
|
|
||||||
|
int y = relY + (sectionIndex * LodUtil.CHUNK_WIDTH) + ChunkWrapper.getMinBuildHeight(chunk);
|
||||||
|
blockLightStorage.set(relX, y, relZ, blockLight);
|
||||||
|
skyLightStorage.set(relX, y, relZ, skyLight);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return combinedStorage;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
/** source: https://minecraft.wiki/w/Chunk_format#Block_Format */
|
||||||
|
private static byte getNibbleAtIndex(byte[] arr, int index)
|
||||||
|
{
|
||||||
|
if (index % 2 == 0)
|
||||||
|
{
|
||||||
|
return (byte)(arr[index/2] & 0x0F);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return (byte)((arr[index/2]>>4) & 0x0F);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void logBlockDeserializationWarning(ChunkPos chunkPos, int sectionYIndex, String message)
|
||||||
|
{
|
||||||
|
LOGGER.warn("Unable to deserialize blocks for chunk section [" + chunkPos.x + ", " + sectionYIndex + ", " + chunkPos.z + "], error: ["+message+"]. This can probably be ignored, although if your world looks wrong, optimizing it via the single player menu then deleting your DH database(s) should fix the problem.");
|
||||||
|
}
|
||||||
|
private static void logBiomeDeserializationWarning(ChunkPos chunkPos, int sectionYIndex, String message)
|
||||||
|
{
|
||||||
|
LOGGER.warn("Unable to deserialize biomes for chunk section [" + chunkPos.x + ", " + sectionYIndex + ", " + chunkPos.z + "], error: ["+message+"]. This can probably be ignored, although if your world looks wrong, optimizing it via the single player menu then deleting your DH database(s) should fix the problem.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//================//
|
||||||
|
// helper classes //
|
||||||
|
//================//
|
||||||
|
|
||||||
|
public static class CombinedChunkLightStorage
|
||||||
|
{
|
||||||
|
public ChunkLightStorage blockLightStorage;
|
||||||
|
public ChunkLightStorage skyLightStorage;
|
||||||
|
|
||||||
|
public CombinedChunkLightStorage(int minY, int maxY)
|
||||||
|
{
|
||||||
|
this.blockLightStorage = ChunkLightStorage.createBlockLightStorage(minY, maxY);
|
||||||
|
this.skyLightStorage = ChunkLightStorage.createSkyLightStorage(minY, maxY);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+23
@@ -0,0 +1,23 @@
|
|||||||
|
package com.seibel.distanthorizons.common.wrappers.worldGeneration.mimicObject;
|
||||||
|
|
||||||
|
#if MC_VER >= MC_1_21
|
||||||
|
|
||||||
|
import net.minecraft.server.level.GenerationChunkHolder;
|
||||||
|
import net.minecraft.world.level.ChunkPos;
|
||||||
|
|
||||||
|
public class DhGenerationChunkHolder extends GenerationChunkHolder
|
||||||
|
{
|
||||||
|
|
||||||
|
public DhGenerationChunkHolder(ChunkPos pos)
|
||||||
|
{
|
||||||
|
super(pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getTicketLevel() { return 0; }
|
||||||
|
@Override
|
||||||
|
public int getQueueLevel() { return 0; }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
+129
-74
@@ -20,14 +20,17 @@
|
|||||||
package com.seibel.distanthorizons.common.wrappers.worldGeneration.mimicObject;
|
package com.seibel.distanthorizons.common.wrappers.worldGeneration.mimicObject;
|
||||||
|
|
||||||
import java.lang.invoke.MethodHandles;
|
import java.lang.invoke.MethodHandles;
|
||||||
|
import java.util.EnumSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.locks.ReentrantLock;
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
|
import com.seibel.distanthorizons.common.wrappers.chunk.ChunkWrapper;
|
||||||
import com.seibel.distanthorizons.common.wrappers.worldGeneration.BatchGenerationEnvironment;
|
import com.seibel.distanthorizons.common.wrappers.worldGeneration.BatchGenerationEnvironment;
|
||||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||||
|
import com.seibel.distanthorizons.core.util.LodUtil;
|
||||||
import net.minecraft.world.level.block.EntityBlock;
|
import net.minecraft.world.level.block.EntityBlock;
|
||||||
import net.minecraft.world.level.block.SpawnerBlock;
|
import net.minecraft.world.level.block.SpawnerBlock;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
|
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
|
||||||
@@ -41,7 +44,7 @@ import net.minecraft.util.Mth;
|
|||||||
import net.minecraft.world.entity.Entity;
|
import net.minecraft.world.entity.Entity;
|
||||||
import net.minecraft.world.level.ChunkPos;
|
import net.minecraft.world.level.ChunkPos;
|
||||||
import net.minecraft.world.level.ColorResolver;
|
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;
|
import net.minecraft.world.level.LevelHeightAccessor;
|
||||||
#endif
|
#endif
|
||||||
import net.minecraft.world.level.LightLayer;
|
import net.minecraft.world.level.LightLayer;
|
||||||
@@ -50,34 +53,50 @@ import net.minecraft.world.level.block.Blocks;
|
|||||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
import net.minecraft.world.level.chunk.ChunkAccess;
|
import net.minecraft.world.level.chunk.ChunkAccess;
|
||||||
import net.minecraft.world.level.chunk.ChunkStatus;
|
|
||||||
import net.minecraft.world.level.chunk.ImposterProtoChunk;
|
import net.minecraft.world.level.chunk.ImposterProtoChunk;
|
||||||
import net.minecraft.world.level.chunk.LevelChunk;
|
import net.minecraft.world.level.chunk.LevelChunk;
|
||||||
import net.minecraft.world.level.lighting.LevelLightEngine;
|
import net.minecraft.world.level.lighting.LevelLightEngine;
|
||||||
|
|
||||||
|
#if MC_VER <= MC_1_20_4
|
||||||
|
import net.minecraft.world.level.chunk.ChunkStatus;
|
||||||
|
#else
|
||||||
|
import net.minecraft.world.level.chunk.status.*;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if MC_VER == MC_1_21
|
||||||
|
import net.minecraft.util.StaticCache2D;
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
|
import net.minecraft.server.level.GenerationChunkHolder;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
public class DhLitWorldGenRegion extends WorldGenRegion
|
public class DhLitWorldGenRegion extends WorldGenRegion
|
||||||
{
|
{
|
||||||
private static final Logger LOGGER = DhLoggerBuilder.getLogger(MethodHandles.lookup().lookupClass().getSimpleName());
|
private static final Logger LOGGER = DhLoggerBuilder.getLogger(MethodHandles.lookup().lookupClass().getSimpleName());
|
||||||
|
|
||||||
|
private static ChunkStatus debugTriggeredForStatus = null;
|
||||||
|
|
||||||
|
|
||||||
public final DummyLightEngine lightEngine;
|
public final DummyLightEngine lightEngine;
|
||||||
public final BatchGenerationEnvironment.EmptyChunkGenerator generator;
|
public final BatchGenerationEnvironment.IEmptyChunkGeneratorFunc generator;
|
||||||
public final int writeRadius;
|
public final int writeRadius;
|
||||||
public final int size;
|
public final int size;
|
||||||
|
|
||||||
private final ChunkPos firstPos;
|
private final ChunkPos firstPos;
|
||||||
private final List<ChunkAccess> cache;
|
private final List<ChunkAccess> cache;
|
||||||
Long2ObjectOpenHashMap<ChunkAccess> chunkMap = new Long2ObjectOpenHashMap<ChunkAccess>();
|
private final Long2ObjectOpenHashMap<ChunkAccess> chunkMap = new Long2ObjectOpenHashMap<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Present to reduce the chance that we accidentally break underlying MC code that isn't thread safe,
|
* Present to reduce the chance that we accidentally break underlying MC code that isn't thread safe,
|
||||||
* specifically: "it.unimi.dsi.fastutil.longs.Long2ObjectLinkedOpenHashMap.getAndMoveToFirst()"
|
* specifically: "it.unimi.dsi.fastutil.longs.Long2ObjectLinkedOpenHashMap.getAndMoveToFirst()"
|
||||||
*/
|
*/
|
||||||
ReentrantLock getChunkLock = new ReentrantLock();
|
private final ReentrantLock getChunkLock = new ReentrantLock();
|
||||||
|
|
||||||
#if PRE_MC_1_18_2
|
#if MC_VER < MC_1_18_2
|
||||||
private ChunkPos overrideCenterPos = null;
|
private ChunkPos overrideCenterPos = null;
|
||||||
|
|
||||||
public void setOverrideCenter(ChunkPos pos) { overrideCenterPos = pos; }
|
public void setOverrideCenter(ChunkPos pos) { overrideCenterPos = pos; }
|
||||||
#if PRE_MC_1_17_1
|
#if MC_VER < MC_1_17_1
|
||||||
@Override
|
@Override
|
||||||
public int getCenterX()
|
public int getCenterX()
|
||||||
{
|
{
|
||||||
@@ -100,12 +119,30 @@ public class DhLitWorldGenRegion extends WorldGenRegion
|
|||||||
|
|
||||||
|
|
||||||
public DhLitWorldGenRegion(
|
public DhLitWorldGenRegion(
|
||||||
|
int centerChunkX, int centerChunkZ,
|
||||||
|
ChunkAccess centerChunk,
|
||||||
ServerLevel serverLevel, DummyLightEngine lightEngine,
|
ServerLevel serverLevel, DummyLightEngine lightEngine,
|
||||||
List<ChunkAccess> chunkList, ChunkStatus chunkStatus, int writeRadius,
|
List<ChunkAccess> chunkList, ChunkStatus chunkStatus, int writeRadius,
|
||||||
BatchGenerationEnvironment.EmptyChunkGenerator generator)
|
BatchGenerationEnvironment.IEmptyChunkGeneratorFunc generator)
|
||||||
{
|
{
|
||||||
super(serverLevel, chunkList #if POST_MC_1_17_1 , chunkStatus, writeRadius #endif );
|
#if MC_VER == MC_1_16_5
|
||||||
this.firstPos = chunkList.get(0).getPos();
|
super(serverLevel, chunkList);
|
||||||
|
#elif MC_VER < MC_1_21
|
||||||
|
super(serverLevel, chunkList, chunkStatus, writeRadius);
|
||||||
|
#else
|
||||||
|
super(serverLevel,
|
||||||
|
StaticCache2D.create(
|
||||||
|
centerChunkX, centerChunkZ,
|
||||||
|
writeRadius * 2, (x,z) -> new DhGenerationChunkHolder(new ChunkPos(x, z))),
|
||||||
|
new ChunkStep(chunkStatus,
|
||||||
|
// reverse is needed because MC uses the index of the chunkStatus to determine how many items are in the list instead of the actual list count
|
||||||
|
new ChunkDependencies(ImmutableList.copyOf(ChunkStatus.getStatusList()).reverse()),
|
||||||
|
new ChunkDependencies(ImmutableList.copyOf(ChunkStatus.getStatusList()).reverse()),
|
||||||
|
writeRadius, (WorldGenContext var1, ChunkStep var2, StaticCache2D<GenerationChunkHolder> var3, ChunkAccess var4) -> null),
|
||||||
|
centerChunk);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
this.firstPos = chunkList.getFirst().getPos();
|
||||||
this.generator = generator;
|
this.generator = generator;
|
||||||
this.lightEngine = lightEngine;
|
this.lightEngine = lightEngine;
|
||||||
this.writeRadius = writeRadius;
|
this.writeRadius = writeRadius;
|
||||||
@@ -115,7 +152,7 @@ public class DhLitWorldGenRegion extends WorldGenRegion
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
#if POST_MC_1_17_1
|
#if MC_VER >= MC_1_17_1
|
||||||
// Bypass BCLib mixin overrides.
|
// Bypass BCLib mixin overrides.
|
||||||
@Override
|
@Override
|
||||||
public boolean ensureCanWrite(BlockPos blockPos)
|
public boolean ensureCanWrite(BlockPos blockPos)
|
||||||
@@ -130,7 +167,7 @@ public class DhLitWorldGenRegion extends WorldGenRegion
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
#if POST_MC_1_18_2
|
#if MC_VER >= MC_1_18_2
|
||||||
if (center.isUpgrading())
|
if (center.isUpgrading())
|
||||||
{
|
{
|
||||||
LevelHeightAccessor levelHeightAccessor = center.getHeightAccessorForGeneration();
|
LevelHeightAccessor levelHeightAccessor = center.getHeightAccessorForGeneration();
|
||||||
@@ -185,7 +222,7 @@ public class DhLitWorldGenRegion extends WorldGenRegion
|
|||||||
BlockState blockState = this.getBlockState(blockPos);
|
BlockState blockState = this.getBlockState(blockPos);
|
||||||
|
|
||||||
// This is a bypass for the spawner block since MC complains about not having it
|
// 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)
|
if (blockState.getBlock() instanceof SpawnerBlock)
|
||||||
{
|
{
|
||||||
return ((EntityBlock) blockState.getBlock()).newBlockEntity(blockPos, blockState);
|
return ((EntityBlock) blockState.getBlock()).newBlockEntity(blockPos, blockState);
|
||||||
@@ -198,12 +235,9 @@ public class DhLitWorldGenRegion extends WorldGenRegion
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Skip BlockEntity stuff. It aren't really needed
|
/** Skip BlockEntity stuff. They aren't needed for our use case. */
|
||||||
@Override
|
@Override
|
||||||
public boolean addFreshEntity(Entity entity)
|
public boolean addFreshEntity(@NotNull Entity entity) { return true; }
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Allays have empty chunks even if it's outside the worldGenRegion
|
// Allays have empty chunks even if it's outside the worldGenRegion
|
||||||
// @Override
|
// @Override
|
||||||
@@ -214,13 +248,13 @@ public class DhLitWorldGenRegion extends WorldGenRegion
|
|||||||
// Override to ensure no other mod mixins cause skipping the overrided
|
// Override to ensure no other mod mixins cause skipping the overrided
|
||||||
// getChunk(...)
|
// getChunk(...)
|
||||||
@Override
|
@Override
|
||||||
public ChunkAccess getChunk(int i, int j)
|
public @NotNull ChunkAccess getChunk(int chunkX, int chunkZ)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// lock is to prevent issues with underlying MC code that doesn't support multithreading
|
// lock is to prevent issues with underlying MC code that doesn't support multithreading
|
||||||
this.getChunkLock.lock();
|
this.getChunkLock.lock();
|
||||||
return this.getChunk(i, j, ChunkStatus.EMPTY);
|
return this.getChunk(chunkX, chunkZ, ChunkStatus.EMPTY);
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
@@ -231,13 +265,19 @@ public class DhLitWorldGenRegion extends WorldGenRegion
|
|||||||
// Override to ensure no other mod mixins cause skipping the overrided
|
// Override to ensure no other mod mixins cause skipping the overrided
|
||||||
// getChunk(...)
|
// getChunk(...)
|
||||||
@Override
|
@Override
|
||||||
public ChunkAccess getChunk(int i, int j, ChunkStatus chunkStatus)
|
public @NotNull ChunkAccess getChunk(int chunkX, int chunkZ, @NotNull ChunkStatus chunkStatus)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// lock is to prevent issues with underlying MC code that doesn't support multithreading
|
// lock is to prevent issues with underlying MC code that doesn't support multithreading
|
||||||
this.getChunkLock.lock();
|
this.getChunkLock.lock();
|
||||||
return this.getChunk(i, j, chunkStatus, true);
|
|
||||||
|
ChunkAccess chunk = this.getChunk(chunkX, chunkZ, chunkStatus, true);
|
||||||
|
if (chunk == null)
|
||||||
|
{
|
||||||
|
LodUtil.assertNotReach("getChunk shouldn't return null values");
|
||||||
|
}
|
||||||
|
return chunk;
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
@@ -245,102 +285,117 @@ public class DhLitWorldGenRegion extends WorldGenRegion
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use this instead of super.getChunk() to bypass C2ME concurrency checks
|
/** Allows creating empty chunks even if they're outside the worldGenRegion */
|
||||||
private ChunkAccess superGetChunk(int x, int z, ChunkStatus cs)
|
|
||||||
{
|
|
||||||
int k = x - firstPos.x;
|
|
||||||
int l = z - firstPos.z;
|
|
||||||
return cache.get(k + l * size);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Use this instead of super.hasChunk() to bypass C2ME concurrency checks
|
|
||||||
public boolean superHasChunk(int x, int z)
|
|
||||||
{
|
|
||||||
int k = x - firstPos.x;
|
|
||||||
int l = z - firstPos.z;
|
|
||||||
return l >= 0 && l < size && k >= 0 && k < size;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Allow creating empty chunks even if it's outside the worldGenRegion
|
|
||||||
@Override
|
@Override
|
||||||
@Nullable
|
@Nullable
|
||||||
public ChunkAccess getChunk(int i, int j, ChunkStatus chunkStatus, boolean bl)
|
public ChunkAccess getChunk(int chunkX, int chunkZ, @NotNull ChunkStatus chunkStatus, boolean returnNonNull)
|
||||||
{
|
{
|
||||||
ChunkAccess chunk = getChunkAccess(i, j, chunkStatus, bl);
|
ChunkAccess chunk = this.getChunkAccess(chunkX, chunkZ, chunkStatus, returnNonNull);
|
||||||
if (chunk instanceof LevelChunk)
|
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;
|
return chunk;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ChunkStatus debugTriggeredForStatus = null;
|
/**
|
||||||
|
* @param returnNonNull if true this method will always return a non-null chunk,
|
||||||
private ChunkAccess getChunkAccess(int i, int j, ChunkStatus chunkStatus, boolean bl)
|
* if false it will return null if no chunk exists at the given position with the given status
|
||||||
|
*/
|
||||||
|
private ChunkAccess getChunkAccess(int chunkX, int chunkZ, ChunkStatus chunkStatus, boolean returnNonNull)
|
||||||
{
|
{
|
||||||
ChunkAccess chunk = superHasChunk(i, j) ? superGetChunk(i, j, ChunkStatus.EMPTY) : null;
|
ChunkAccess chunk = this.superHasChunk(chunkX, chunkZ) ? this.superGetChunk(chunkX, chunkZ) : null;
|
||||||
if (chunk != null && chunk.getStatus().isOrAfter(chunkStatus))
|
if (chunk != null && ChunkWrapper.getStatus(chunk).isOrAfter(chunkStatus))
|
||||||
{
|
{
|
||||||
return chunk;
|
return chunk;
|
||||||
}
|
}
|
||||||
if (!bl)
|
else if (!returnNonNull)
|
||||||
|
{
|
||||||
|
// no chunk found with the necessary status and null return values are allowed
|
||||||
return null;
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// we need a non-null chunk
|
||||||
if (chunk == null)
|
if (chunk == null)
|
||||||
{
|
{
|
||||||
chunk = chunkMap.get(ChunkPos.asLong(i, j));
|
// check memory
|
||||||
|
chunk = this.chunkMap.get(ChunkPos.asLong(chunkX, chunkZ));
|
||||||
if (chunk == null)
|
if (chunk == null)
|
||||||
{
|
{
|
||||||
chunk = generator.generate(i, j);
|
// chunk isn't in memory, generate a new one
|
||||||
|
chunk = this.generator.generate(chunkX, chunkZ);
|
||||||
if (chunk == null)
|
if (chunk == null)
|
||||||
|
{
|
||||||
throw new NullPointerException("The provided generator should not return null!");
|
throw new NullPointerException("The provided generator should not return null!");
|
||||||
chunkMap.put(ChunkPos.asLong(i, j), chunk);
|
}
|
||||||
|
this.chunkMap.put(ChunkPos.asLong(chunkX, chunkZ), chunk);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (chunkStatus != ChunkStatus.EMPTY && chunkStatus != debugTriggeredForStatus)
|
if (chunkStatus != ChunkStatus.EMPTY && chunkStatus != debugTriggeredForStatus)
|
||||||
{
|
{
|
||||||
LOGGER.info("WorldGen requiring " + chunkStatus
|
LOGGER.info("WorldGen requiring " + chunkStatus
|
||||||
+ " outside expected range detected. Force passing EMPTY chunk and seeing if it works.");
|
+ " outside expected range detected. Force passing EMPTY chunk and seeing if it works.");
|
||||||
debugTriggeredForStatus = chunkStatus;
|
debugTriggeredForStatus = chunkStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
return chunk;
|
return chunk;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Overriding allows us to use our own lighting engine */
|
/** Use this instead of super.hasChunk() to bypass C2ME concurrency checks */
|
||||||
@Override
|
public boolean superHasChunk(int x, int z)
|
||||||
public LevelLightEngine getLightEngine() { return this.lightEngine; }
|
|
||||||
|
|
||||||
/** Overriding allows us to use our own lighting engine */
|
|
||||||
@Override
|
|
||||||
public int getBrightness(LightLayer lightLayer, BlockPos blockPos) { return 0; }
|
|
||||||
|
|
||||||
/** Overriding allows us to use our own lighting engine */
|
|
||||||
@Override
|
|
||||||
public int getRawBrightness(BlockPos blockPos, int i) { return 0; }
|
|
||||||
|
|
||||||
/** Overriding allows us to use our own lighting engine */
|
|
||||||
@Override
|
|
||||||
public boolean canSeeSky(BlockPos blockPos)
|
|
||||||
{
|
{
|
||||||
return (getBrightness(LightLayer.SKY, blockPos) >= getMaxLightLevel());
|
int k = x - this.firstPos.x;
|
||||||
|
int l = z - this.firstPos.z;
|
||||||
|
return l >= 0 && l < this.size && k >= 0 && k < this.size;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getBlockTint(BlockPos blockPos, ColorResolver colorResolver)
|
/** Use this instead of super.getChunk() to bypass C2ME concurrency checks */
|
||||||
|
private ChunkAccess superGetChunk(int x, int z)
|
||||||
{
|
{
|
||||||
return calculateBlockTint(blockPos, colorResolver);
|
int k = x - this.firstPos.x;
|
||||||
|
int l = z - this.firstPos.z;
|
||||||
|
return this.cache.get(k + l * this.size);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Overriding allows us to use our own lighting engine */
|
||||||
|
@Override
|
||||||
|
public @NotNull LevelLightEngine getLightEngine() { return this.lightEngine; }
|
||||||
|
|
||||||
|
/** Overriding allows us to use our own lighting engine */
|
||||||
|
@Override
|
||||||
|
public int getBrightness(@NotNull LightLayer lightLayer, @NotNull BlockPos blockPos) { return 0; }
|
||||||
|
|
||||||
|
/** Overriding allows us to use our own lighting engine */
|
||||||
|
@Override
|
||||||
|
public int getRawBrightness(@NotNull BlockPos blockPos, int i) { return 0; }
|
||||||
|
|
||||||
|
/** Overriding allows us to use our own lighting engine */
|
||||||
|
@Override
|
||||||
|
public boolean canSeeSky(@NotNull BlockPos blockPos)
|
||||||
|
{
|
||||||
|
return (this.getBrightness(LightLayer.SKY, blockPos) >= this.getMaxLightLevel());
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getBlockTint(@NotNull BlockPos blockPos, @NotNull ColorResolver colorResolver)
|
||||||
|
{
|
||||||
|
return this.calculateBlockTint(blockPos, colorResolver);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Biome _getBiome(BlockPos pos)
|
private Biome _getBiome(BlockPos pos)
|
||||||
{
|
{
|
||||||
#if POST_MC_1_18_2
|
#if MC_VER >= MC_1_18_2
|
||||||
return getBiome(pos).value();
|
return this.getBiome(pos).value();
|
||||||
#else
|
#else
|
||||||
return getBiome(pos);
|
return this.getBiome(pos);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
public int calculateBlockTint(BlockPos blockPos, ColorResolver colorResolver)
|
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;
|
int i = (Minecraft.getInstance()).options.biomeBlendRadius;
|
||||||
#else
|
#else
|
||||||
int i = (Minecraft.getInstance()).options.biomeBlendRadius().get();
|
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
|
@Override
|
||||||
public void onBlockEmissionIncrease(BlockPos blockPos, int i) { }
|
public void onBlockEmissionIncrease(BlockPos blockPos, int i) { }
|
||||||
|
|
||||||
@@ -63,7 +63,7 @@ public class DummyLightEngine extends LevelLightEngine
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
@Override
|
@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
|
@Override
|
||||||
public void checkBlock(BlockPos blockPos) { }
|
public void checkBlock(BlockPos blockPos) { }
|
||||||
@@ -87,7 +87,7 @@ public class DummyLightEngine extends LevelLightEngine
|
|||||||
@Override
|
@Override
|
||||||
public void retainData(ChunkPos chunkPos, boolean bl) { }
|
public void retainData(ChunkPos chunkPos, boolean bl) { }
|
||||||
|
|
||||||
#if POST_MC_1_17_1
|
#if MC_VER >= MC_1_17_1
|
||||||
@Override
|
@Override
|
||||||
public int getLightSectionCount() { throw new UnsupportedOperationException("This should never be used!"); }
|
public int getLightSectionCount() { throw new UnsupportedOperationException("This should never be used!"); }
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
+15
-6
@@ -23,15 +23,24 @@ import com.seibel.distanthorizons.core.dependencyInjection.ModAccessorInjector;
|
|||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IStarlightAccessor;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IStarlightAccessor;
|
||||||
|
|
||||||
import net.minecraft.world.level.BlockGetter;
|
import net.minecraft.world.level.BlockGetter;
|
||||||
#if POST_MC_1_17_1
|
import net.minecraft.world.level.chunk.LightChunkGetter;
|
||||||
|
|
||||||
|
#if MC_VER >= MC_1_17_1
|
||||||
import net.minecraft.world.level.LevelHeightAccessor;
|
import net.minecraft.world.level.LevelHeightAccessor;
|
||||||
#endif
|
#endif
|
||||||
import net.minecraft.world.level.chunk.ChunkStatus;
|
|
||||||
import net.minecraft.world.level.chunk.LightChunkGetter;
|
#if MC_VER >= MC_1_20_1
|
||||||
#if POST_MC_1_20_1
|
|
||||||
import net.minecraft.world.level.chunk.LightChunk;
|
import net.minecraft.world.level.chunk.LightChunk;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if MC_VER <= MC_1_20_4
|
||||||
|
import net.minecraft.world.level.chunk.ChunkStatus;
|
||||||
|
#else
|
||||||
|
import net.minecraft.world.level.chunk.status.ChunkStatus;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public class LightGetterAdaptor implements LightChunkGetter
|
public class LightGetterAdaptor implements LightChunkGetter
|
||||||
{
|
{
|
||||||
private final BlockGetter heightGetter;
|
private final BlockGetter heightGetter;
|
||||||
@@ -50,7 +59,7 @@ public class LightGetterAdaptor implements LightChunkGetter
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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)
|
if (genRegion == null)
|
||||||
throw new IllegalStateException("World Gen region has not been set!");
|
throw new IllegalStateException("World Gen region has not been set!");
|
||||||
@@ -64,7 +73,7 @@ public class LightGetterAdaptor implements LightChunkGetter
|
|||||||
return shouldReturnNull ? null : (genRegion != null ? genRegion : heightGetter);
|
return shouldReturnNull ? null : (genRegion != null ? genRegion : heightGetter);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if POST_MC_1_17_1
|
#if MC_VER >= MC_1_17_1
|
||||||
public LevelHeightAccessor getLevelHeightAccessor()
|
public LevelHeightAccessor getLevelHeightAccessor()
|
||||||
{
|
{
|
||||||
return heightGetter;
|
return heightGetter;
|
||||||
|
|||||||
+52
-6
@@ -1,13 +1,15 @@
|
|||||||
package com.seibel.distanthorizons.common.wrappers.worldGeneration.mimicObject;
|
package com.seibel.distanthorizons.common.wrappers.worldGeneration.mimicObject;
|
||||||
|
|
||||||
import com.seibel.distanthorizons.common.wrappers.worldGeneration.BatchGenerationEnvironment;
|
import com.seibel.distanthorizons.common.wrappers.worldGeneration.BatchGenerationEnvironment;
|
||||||
|
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||||
import net.minecraft.nbt.CompoundTag;
|
import net.minecraft.nbt.CompoundTag;
|
||||||
import net.minecraft.nbt.NbtIo;
|
import net.minecraft.nbt.NbtIo;
|
||||||
import net.minecraft.world.level.ChunkPos;
|
import net.minecraft.world.level.ChunkPos;
|
||||||
import net.minecraft.world.level.chunk.storage.RegionFile;
|
import net.minecraft.world.level.chunk.storage.RegionFile;
|
||||||
import net.minecraft.world.level.chunk.storage.RegionFileStorage;
|
import net.minecraft.world.level.chunk.storage.RegionFileStorage;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import java.io.DataInputStream;
|
import java.io.DataInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
@@ -15,11 +17,27 @@ import java.nio.file.Path;
|
|||||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||||
import java.util.concurrent.locks.ReentrantLock;
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
|
|
||||||
|
#if MC_VER >= MC_1_20_6
|
||||||
|
import net.minecraft.world.level.chunk.storage.RegionStorageInfo;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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
|
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 final RegionFileStorage storage;
|
||||||
public static final int MAX_CACHE_SIZE = 16;
|
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,
|
* 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()"
|
* specifically: "it.unimi.dsi.fastutil.longs.Long2ObjectLinkedOpenHashMap.getAndMoveToFirst()"
|
||||||
@@ -50,6 +68,19 @@ public class RegionFileStorageExternalCache implements AutoCloseable
|
|||||||
@Nullable
|
@Nullable
|
||||||
public RegionFile getRegionFile(ChunkPos pos) throws IOException
|
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());
|
long posLong = ChunkPos.asLong(pos.getRegionX(), pos.getRegionZ());
|
||||||
RegionFile rFile = null;
|
RegionFile rFile = null;
|
||||||
|
|
||||||
@@ -64,7 +95,7 @@ public class RegionFileStorageExternalCache implements AutoCloseable
|
|||||||
{
|
{
|
||||||
this.getRegionFileLock.lock();
|
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);
|
rFile = this.storage.getRegionFile(pos);
|
||||||
|
|
||||||
// keeping the region cache size low helps prevent concurrency issues
|
// keeping the region cache size low helps prevent concurrency issues
|
||||||
@@ -84,7 +115,7 @@ public class RegionFileStorageExternalCache implements AutoCloseable
|
|||||||
}
|
}
|
||||||
catch (ArrayIndexOutOfBoundsException e)
|
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
|
// the file just wasn't cached
|
||||||
break;
|
break;
|
||||||
#else
|
#else
|
||||||
@@ -98,6 +129,19 @@ public class RegionFileStorageExternalCache implements AutoCloseable
|
|||||||
}
|
}
|
||||||
#endif
|
#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
|
finally
|
||||||
{
|
{
|
||||||
this.getRegionFileLock.unlock();
|
this.getRegionFileLock.unlock();
|
||||||
@@ -126,7 +170,7 @@ public class RegionFileStorageExternalCache implements AutoCloseable
|
|||||||
|
|
||||||
// Otherwise, check if file exist, and if so, add it to the cache
|
// Otherwise, check if file exist, and if so, add it to the cache
|
||||||
Path storageFolderPath;
|
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();
|
storageFolderPath = this.storage.folder.toPath();
|
||||||
#else
|
#else
|
||||||
storageFolderPath = this.storage.folder;
|
storageFolderPath = this.storage.folder;
|
||||||
@@ -138,10 +182,12 @@ public class RegionFileStorageExternalCache implements AutoCloseable
|
|||||||
}
|
}
|
||||||
|
|
||||||
Path regionFilePath = storageFolderPath.resolve("r." + pos.getRegionX() + "." + pos.getRegionZ() + ".mca");
|
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);
|
rFile = new RegionFile(regionFilePath.toFile(), storageFolderPath.toFile(), false);
|
||||||
#else
|
#elif MC_VER <= MC_1_20_4
|
||||||
rFile = new RegionFile(regionFilePath, storageFolderPath, false);
|
rFile = new RegionFile(regionFilePath, storageFolderPath, false);
|
||||||
|
#else
|
||||||
|
rFile = new RegionFile(new RegionStorageInfo("level", null, "level type"), regionFilePath, storageFolderPath, false);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
this.regionFileCache.add(new RegionFileCache(ChunkPos.asLong(pos.getRegionX(), pos.getRegionZ()), rFile));
|
this.regionFileCache.add(new RegionFileCache(ChunkPos.asLong(pos.getRegionX(), pos.getRegionZ()), rFile));
|
||||||
|
|||||||
+22
-19
@@ -35,51 +35,56 @@ import net.minecraft.server.level.WorldGenRegion;
|
|||||||
import net.minecraft.world.level.ChunkPos;
|
import net.minecraft.world.level.ChunkPos;
|
||||||
import net.minecraft.world.level.WorldGenLevel;
|
import net.minecraft.world.level.WorldGenLevel;
|
||||||
import net.minecraft.world.level.chunk.ChunkAccess;
|
import net.minecraft.world.level.chunk.ChunkAccess;
|
||||||
import net.minecraft.world.level.chunk.ChunkStatus;
|
|
||||||
import net.minecraft.world.level.levelgen.WorldGenSettings;
|
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.levelgen.feature.ConfiguredStructureFeature;
|
||||||
import net.minecraft.world.level.StructureFeatureManager;
|
import net.minecraft.world.level.StructureFeatureManager;
|
||||||
#else
|
#else
|
||||||
#if POST_MC_1_19_4
|
#if MC_VER >= MC_1_19_4
|
||||||
import net.minecraft.world.level.levelgen.WorldOptions;
|
import net.minecraft.world.level.levelgen.WorldOptions;
|
||||||
#endif
|
#endif
|
||||||
import net.minecraft.world.level.levelgen.structure.Structure;
|
import net.minecraft.world.level.levelgen.structure.Structure;
|
||||||
import net.minecraft.world.level.StructureManager;
|
import net.minecraft.world.level.StructureManager;
|
||||||
#endif
|
#endif
|
||||||
#if POST_MC_1_18_2
|
#if MC_VER >= MC_1_18_2
|
||||||
import net.minecraft.world.level.levelgen.structure.StructureCheck;
|
import net.minecraft.world.level.levelgen.structure.StructureCheck;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
import net.minecraft.world.level.levelgen.structure.StructureStart;
|
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;
|
import net.minecraft.world.level.levelgen.feature.StructureFeature;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if MC_VER <= MC_1_20_4
|
||||||
|
import net.minecraft.world.level.chunk.ChunkStatus;
|
||||||
|
#else
|
||||||
|
import net.minecraft.world.level.chunk.status.ChunkStatus;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public 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;
|
final WorldGenLevel genLevel;
|
||||||
|
|
||||||
#if PRE_MC_1_19_4
|
#if MC_VER < MC_1_19_4
|
||||||
WorldGenSettings worldGenSettings;
|
WorldGenSettings worldGenSettings;
|
||||||
#else
|
#else
|
||||||
WorldOptions worldOptions;
|
WorldOptions worldOptions;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if POST_MC_1_18_2
|
#if MC_VER >= MC_1_18_2
|
||||||
StructureCheck structureCheck;
|
StructureCheck structureCheck;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if PRE_MC_1_19_4
|
#if MC_VER < MC_1_19_4
|
||||||
public WorldGenStructFeatManager(
|
public WorldGenStructFeatManager(
|
||||||
WorldGenSettings worldGenSettings,
|
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.genLevel = genLevel;
|
||||||
this.worldGenSettings = worldGenSettings;
|
this.worldGenSettings = worldGenSettings;
|
||||||
}
|
}
|
||||||
@@ -100,8 +105,8 @@ public class WorldGenStructFeatManager extends #if PRE_MC_1_19_2 StructureFeatur
|
|||||||
{
|
{
|
||||||
if (worldGenRegion == genLevel)
|
if (worldGenRegion == genLevel)
|
||||||
return this;
|
return this;
|
||||||
#if PRE_MC_1_19_4
|
#if MC_VER < MC_1_19_4
|
||||||
return new WorldGenStructFeatManager(worldGenSettings, worldGenRegion #if POST_MC_1_18_2 , structureCheck #endif );
|
return new WorldGenStructFeatManager(worldGenSettings, worldGenRegion #if MC_VER >= MC_1_18_2 , structureCheck #endif );
|
||||||
#else
|
#else
|
||||||
return new WorldGenStructFeatManager(worldOptions, worldGenRegion, structureCheck);
|
return new WorldGenStructFeatManager(worldOptions, worldGenRegion, structureCheck);
|
||||||
#endif
|
#endif
|
||||||
@@ -113,7 +118,7 @@ public class WorldGenStructFeatManager extends #if PRE_MC_1_19_2 StructureFeatur
|
|||||||
return genLevel.getChunk(x, z, status, false);
|
return genLevel.getChunk(x, z, status, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if PRE_MC_1_18_2
|
#if MC_VER < MC_1_18_2
|
||||||
@Override
|
@Override
|
||||||
public Stream<? extends StructureStart<?>> startsForFeature(
|
public Stream<? extends StructureStart<?>> startsForFeature(
|
||||||
SectionPos sectionPos2,
|
SectionPos sectionPos2,
|
||||||
@@ -140,7 +145,7 @@ public class WorldGenStructFeatManager extends #if PRE_MC_1_19_2 StructureFeatur
|
|||||||
return chunk.hasAnyStructureReferences();
|
return chunk.hasAnyStructureReferences();
|
||||||
}
|
}
|
||||||
|
|
||||||
#if MC_1_18_1
|
#if MC_VER == MC_1_18_1
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||||
public List<? extends StructureStart<?>> startsForFeature(SectionPos sectionPos,
|
public List<? extends StructureStart<?>> startsForFeature(SectionPos sectionPos,
|
||||||
@@ -165,7 +170,7 @@ public class WorldGenStructFeatManager extends #if PRE_MC_1_19_2 StructureFeatur
|
|||||||
return builder.build();
|
return builder.build();
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
#if PRE_MC_1_19_2
|
#if MC_VER < MC_1_19_2
|
||||||
@Override
|
@Override
|
||||||
public List<StructureStart> startsForFeature(SectionPos sectionPos, Predicate<ConfiguredStructureFeature<?, ?>> predicate)
|
public List<StructureStart> startsForFeature(SectionPos sectionPos, Predicate<ConfiguredStructureFeature<?, ?>> predicate)
|
||||||
{
|
{
|
||||||
@@ -226,11 +231,9 @@ public class WorldGenStructFeatManager extends #if PRE_MC_1_19_2 StructureFeatur
|
|||||||
Map<Structure, LongSet> map = chunk.getAllReferences();
|
Map<Structure, LongSet> map = chunk.getAllReferences();
|
||||||
|
|
||||||
ImmutableList.Builder<StructureStart> builder = ImmutableList.builder();
|
ImmutableList.Builder<StructureStart> builder = ImmutableList.builder();
|
||||||
Iterator<Map.Entry<Structure, LongSet>> var5 = map.entrySet().iterator();
|
|
||||||
|
|
||||||
while (var5.hasNext())
|
for (Map.Entry<Structure, LongSet> entry : map.entrySet())
|
||||||
{
|
{
|
||||||
Map.Entry<Structure, LongSet> entry = var5.next();
|
|
||||||
Structure configuredStructureFeature = entry.getKey();
|
Structure configuredStructureFeature = entry.getKey();
|
||||||
if (predicate.test(configuredStructureFeature))
|
if (predicate.test(configuredStructureFeature))
|
||||||
{
|
{
|
||||||
|
|||||||
+32
-13
@@ -27,15 +27,19 @@ import com.seibel.distanthorizons.common.wrappers.worldGeneration.BatchGeneratio
|
|||||||
import com.seibel.distanthorizons.common.wrappers.worldGeneration.ThreadedParameters;
|
import com.seibel.distanthorizons.common.wrappers.worldGeneration.ThreadedParameters;
|
||||||
|
|
||||||
import net.minecraft.server.level.WorldGenRegion;
|
import net.minecraft.server.level.WorldGenRegion;
|
||||||
#if PRE_MC_1_19_2
|
|
||||||
#endif
|
|
||||||
import net.minecraft.world.level.chunk.ChunkAccess;
|
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.chunk.ProtoChunk;
|
||||||
#if POST_MC_1_18_2
|
|
||||||
|
#if MC_VER >= MC_1_18_2
|
||||||
import net.minecraft.world.level.levelgen.blending.Blender;
|
import net.minecraft.world.level.levelgen.blending.Blender;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if MC_VER <= MC_1_20_4
|
||||||
|
import net.minecraft.world.level.chunk.ChunkStatus;
|
||||||
|
#else
|
||||||
|
import net.minecraft.world.level.chunk.status.ChunkStatus;
|
||||||
|
#endif
|
||||||
|
|
||||||
public final class StepBiomes
|
public final class StepBiomes
|
||||||
{
|
{
|
||||||
public static final ChunkStatus STATUS = ChunkStatus.BIOMES;
|
public static final ChunkStatus STATUS = ChunkStatus.BIOMES;
|
||||||
@@ -52,29 +56,44 @@ public final class StepBiomes
|
|||||||
List<ChunkWrapper> chunkWrappers)
|
List<ChunkWrapper> chunkWrappers)
|
||||||
{
|
{
|
||||||
|
|
||||||
ArrayList<ChunkAccess> chunksToDo = new ArrayList<ChunkAccess>();
|
ArrayList<ChunkAccess> chunksToDo = new ArrayList<>();
|
||||||
|
|
||||||
for (ChunkWrapper chunkWrapper : chunkWrappers)
|
for (ChunkWrapper chunkWrapper : chunkWrappers)
|
||||||
{
|
{
|
||||||
ChunkAccess chunk = chunkWrapper.getChunk();
|
ChunkAccess chunk = chunkWrapper.getChunk();
|
||||||
if (chunk.getStatus().isOrAfter(STATUS)) continue;
|
if (chunkWrapper.getStatus().isOrAfter(STATUS))
|
||||||
|
{
|
||||||
|
// this chunk has already generated this step
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if (chunk instanceof ProtoChunk)
|
||||||
|
{
|
||||||
|
#if MC_VER < MC_1_21
|
||||||
((ProtoChunk) chunk).setStatus(STATUS);
|
((ProtoChunk) chunk).setStatus(STATUS);
|
||||||
|
#else
|
||||||
|
((ProtoChunk) chunk).setPersistedStatus(STATUS);
|
||||||
|
#endif
|
||||||
|
|
||||||
chunksToDo.add(chunk);
|
chunksToDo.add(chunk);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (ChunkAccess chunk : chunksToDo)
|
for (ChunkAccess chunk : chunksToDo)
|
||||||
{
|
{
|
||||||
// System.out.println("StepBiomes: "+chunk.getPos());
|
// 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);
|
this.environment.params.generator.createBiomes(this.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),
|
chunk = this.environment.joinSync(this.environment.params.generator.createBiomes(this.environment.params.biomes, Runnable::run, Blender.of(worldGenRegion),
|
||||||
tParams.structFeat.forWorldGenRegion(worldGenRegion), chunk));
|
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),
|
chunk = this.environment.joinSync(this.environment.params.generator.createBiomes(this.environment.params.biomes, Runnable::run, this.environment.params.randomState, Blender.of(worldGenRegion),
|
||||||
|
tParams.structFeat.forWorldGenRegion(worldGenRegion), chunk));
|
||||||
|
#elif MC_VER < MC_1_21
|
||||||
|
chunk = this.environment.joinSync(this.environment.params.generator.createBiomes(Runnable::run, this.environment.params.randomState, Blender.of(worldGenRegion),
|
||||||
tParams.structFeat.forWorldGenRegion(worldGenRegion), chunk));
|
tParams.structFeat.forWorldGenRegion(worldGenRegion), chunk));
|
||||||
#else
|
#else
|
||||||
chunk = environment.joinSync(environment.params.generator.createBiomes(Runnable::run, environment.params.randomState, Blender.of(worldGenRegion),
|
chunk = this.environment.joinSync(this.environment.params.generator.createBiomes(this.environment.params.randomState, Blender.of(worldGenRegion),
|
||||||
tParams.structFeat.forWorldGenRegion(worldGenRegion), chunk));
|
tParams.structFeat.forWorldGenRegion(worldGenRegion), chunk));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|||||||
+33
-16
@@ -19,24 +19,29 @@
|
|||||||
|
|
||||||
package com.seibel.distanthorizons.common.wrappers.worldGeneration.step;
|
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.chunk.ChunkWrapper;
|
||||||
import com.seibel.distanthorizons.common.wrappers.worldGeneration.BatchGenerationEnvironment;
|
import com.seibel.distanthorizons.common.wrappers.worldGeneration.BatchGenerationEnvironment;
|
||||||
import com.seibel.distanthorizons.common.wrappers.worldGeneration.ThreadedParameters;
|
import com.seibel.distanthorizons.common.wrappers.worldGeneration.ThreadedParameters;
|
||||||
import com.seibel.distanthorizons.common.wrappers.worldGeneration.mimicObject.DhLitWorldGenRegion;
|
import com.seibel.distanthorizons.common.wrappers.worldGeneration.mimicObject.DhLitWorldGenRegion;
|
||||||
|
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||||
import com.seibel.distanthorizons.core.util.gridList.ArrayGridList;
|
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.ChunkAccess;
|
||||||
import net.minecraft.world.level.chunk.ChunkStatus;
|
|
||||||
import net.minecraft.world.level.chunk.ProtoChunk;
|
import net.minecraft.world.level.chunk.ProtoChunk;
|
||||||
import net.minecraft.world.level.levelgen.Heightmap;
|
import net.minecraft.world.level.levelgen.Heightmap;
|
||||||
#if POST_MC_1_18_2
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
|
#if MC_VER <= MC_1_20_4
|
||||||
|
import net.minecraft.world.level.chunk.ChunkStatus;
|
||||||
|
#else
|
||||||
|
import net.minecraft.world.level.chunk.status.ChunkStatus;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
public final class StepFeatures
|
public final class StepFeatures
|
||||||
{
|
{
|
||||||
|
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
|
||||||
|
|
||||||
public static final ChunkStatus STATUS = ChunkStatus.FEATURES;
|
public static final ChunkStatus STATUS = ChunkStatus.FEATURES;
|
||||||
|
|
||||||
private final BatchGenerationEnvironment environment;
|
private final BatchGenerationEnvironment environment;
|
||||||
@@ -51,34 +56,46 @@ public final class StepFeatures
|
|||||||
ThreadedParameters tParams, DhLitWorldGenRegion worldGenRegion,
|
ThreadedParameters tParams, DhLitWorldGenRegion worldGenRegion,
|
||||||
ArrayGridList<ChunkWrapper> chunkWrappers)
|
ArrayGridList<ChunkWrapper> chunkWrappers)
|
||||||
{
|
{
|
||||||
ArrayList<ChunkAccess> chunksToDo = new ArrayList<ChunkAccess>();
|
|
||||||
|
|
||||||
for (ChunkWrapper chunkWrapper : chunkWrappers)
|
for (ChunkWrapper chunkWrapper : chunkWrappers)
|
||||||
{
|
{
|
||||||
ChunkAccess chunk = chunkWrapper.getChunk();
|
ChunkAccess chunk = chunkWrapper.getChunk();
|
||||||
if (chunk.getStatus().isOrAfter(STATUS)) continue;
|
if (chunkWrapper.getStatus().isOrAfter(STATUS))
|
||||||
|
{
|
||||||
|
// this chunk has already generated this step
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if (chunk instanceof ProtoChunk)
|
||||||
|
{
|
||||||
|
#if MC_VER < MC_1_21
|
||||||
((ProtoChunk) chunk).setStatus(STATUS);
|
((ProtoChunk) chunk).setStatus(STATUS);
|
||||||
chunksToDo.add(chunk);
|
#else
|
||||||
|
((ProtoChunk) chunk).setPersistedStatus(STATUS);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
for (ChunkAccess chunk : chunksToDo)
|
|
||||||
{
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
#if PRE_MC_1_18_2
|
#if MC_VER < MC_1_18_2
|
||||||
worldGenRegion.setOverrideCenter(chunk.getPos());
|
worldGenRegion.setOverrideCenter(chunk.getPos());
|
||||||
environment.params.generator.applyBiomeDecoration(worldGenRegion, tParams.structFeat);
|
environment.params.generator.applyBiomeDecoration(worldGenRegion, tParams.structFeat);
|
||||||
#else
|
#else
|
||||||
environment.params.generator.applyBiomeDecoration(worldGenRegion, chunk,
|
if (worldGenRegion.hasChunk(chunkWrapper.getChunkPos().x, chunkWrapper.getChunkPos().z))
|
||||||
tParams.structFeat.forWorldGenRegion(worldGenRegion));
|
{
|
||||||
|
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
|
#endif
|
||||||
|
|
||||||
Heightmap.primeHeightmaps(chunk, STATUS.heightmapsAfter());
|
Heightmap.primeHeightmaps(chunk, STATUS.heightmapsAfter());
|
||||||
BatchGenerationEnvironment.clearDistantGenerationMixinData();
|
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
|
// FIXME: Features concurrent modification issue. Something about cocobeans might just
|
||||||
// error out. For now just retry.
|
// error out. For now just retry.
|
||||||
}
|
}
|
||||||
|
|||||||
+28
-15
@@ -28,17 +28,19 @@ import com.seibel.distanthorizons.common.wrappers.worldGeneration.ThreadedParame
|
|||||||
|
|
||||||
import com.seibel.distanthorizons.core.util.objects.UncheckedInterruptedException;
|
import com.seibel.distanthorizons.core.util.objects.UncheckedInterruptedException;
|
||||||
import net.minecraft.server.level.WorldGenRegion;
|
import net.minecraft.server.level.WorldGenRegion;
|
||||||
#if POST_MC_1_17_1
|
|
||||||
#endif
|
|
||||||
#if PRE_MC_1_19_2
|
|
||||||
#endif
|
|
||||||
import net.minecraft.world.level.chunk.ChunkAccess;
|
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.chunk.ProtoChunk;
|
||||||
#if POST_MC_1_18_2
|
|
||||||
|
#if MC_VER >= MC_1_18_2
|
||||||
import net.minecraft.world.level.levelgen.blending.Blender;
|
import net.minecraft.world.level.levelgen.blending.Blender;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if MC_VER <= MC_1_20_4
|
||||||
|
import net.minecraft.world.level.chunk.ChunkStatus;
|
||||||
|
#else
|
||||||
|
import net.minecraft.world.level.chunk.status.ChunkStatus;
|
||||||
|
#endif
|
||||||
|
|
||||||
public final class StepNoise
|
public final class StepNoise
|
||||||
{
|
{
|
||||||
private static final ChunkStatus STATUS = ChunkStatus.NOISE;
|
private static final ChunkStatus STATUS = ChunkStatus.NOISE;
|
||||||
@@ -56,29 +58,40 @@ public final class StepNoise
|
|||||||
List<ChunkWrapper> chunkWrappers)
|
List<ChunkWrapper> chunkWrappers)
|
||||||
{
|
{
|
||||||
|
|
||||||
ArrayList<ChunkAccess> chunksToDo = new ArrayList<ChunkAccess>();
|
ArrayList<ChunkAccess> chunksToDo = new ArrayList<>();
|
||||||
|
|
||||||
for (ChunkWrapper chunkWrapper : chunkWrappers)
|
for (ChunkWrapper chunkWrapper : chunkWrappers)
|
||||||
{
|
{
|
||||||
ChunkAccess chunk = chunkWrapper.getChunk();
|
ChunkAccess chunk = chunkWrapper.getChunk();
|
||||||
if (chunk.getStatus().isOrAfter(STATUS)) continue;
|
if (chunkWrapper.getStatus().isOrAfter(STATUS))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if MC_VER < MC_1_21
|
||||||
((ProtoChunk) chunk).setStatus(STATUS);
|
((ProtoChunk) chunk).setStatus(STATUS);
|
||||||
|
#else
|
||||||
|
((ProtoChunk) chunk).setPersistedStatus(STATUS);
|
||||||
|
#endif
|
||||||
chunksToDo.add(chunk);
|
chunksToDo.add(chunk);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (ChunkAccess chunk : chunksToDo)
|
for (ChunkAccess chunk : chunksToDo)
|
||||||
{
|
{
|
||||||
// System.out.println("StepNoise: "+chunk.getPos());
|
// 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);
|
this.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,
|
chunk = this.environment.joinSync(this.environment.params.generator.fillFromNoise(Runnable::run,
|
||||||
tParams.structFeat.forWorldGenRegion(worldGenRegion), chunk));
|
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),
|
chunk = this.environment.joinSync(this.environment.params.generator.fillFromNoise(Runnable::run, Blender.of(worldGenRegion),
|
||||||
|
tParams.structFeat.forWorldGenRegion(worldGenRegion), chunk));
|
||||||
|
#elif MC_VER < MC_1_21
|
||||||
|
chunk = this.environment.joinSync(this.environment.params.generator.fillFromNoise(Runnable::run, Blender.of(worldGenRegion), this.environment.params.randomState,
|
||||||
tParams.structFeat.forWorldGenRegion(worldGenRegion), chunk));
|
tParams.structFeat.forWorldGenRegion(worldGenRegion), chunk));
|
||||||
#else
|
#else
|
||||||
chunk = environment.joinSync(environment.params.generator.fillFromNoise(Runnable::run, Blender.of(worldGenRegion), environment.params.randomState,
|
chunk = this.environment.joinSync(this.environment.params.generator.fillFromNoise(Blender.of(worldGenRegion), this.environment.params.randomState,
|
||||||
tParams.structFeat.forWorldGenRegion(worldGenRegion), chunk));
|
tParams.structFeat.forWorldGenRegion(worldGenRegion), chunk));
|
||||||
#endif
|
#endif
|
||||||
UncheckedInterruptedException.throwIfInterrupted();
|
UncheckedInterruptedException.throwIfInterrupted();
|
||||||
|
|||||||
+20
-5
@@ -27,12 +27,16 @@ import com.seibel.distanthorizons.common.wrappers.worldGeneration.BatchGeneratio
|
|||||||
import com.seibel.distanthorizons.common.wrappers.worldGeneration.ThreadedParameters;
|
import com.seibel.distanthorizons.common.wrappers.worldGeneration.ThreadedParameters;
|
||||||
|
|
||||||
import net.minecraft.server.level.WorldGenRegion;
|
import net.minecraft.server.level.WorldGenRegion;
|
||||||
#if PRE_MC_1_19_2
|
|
||||||
#endif
|
|
||||||
import net.minecraft.world.level.chunk.ChunkAccess;
|
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.chunk.ProtoChunk;
|
||||||
|
|
||||||
|
#if MC_VER <= MC_1_20_4
|
||||||
|
import net.minecraft.world.level.chunk.ChunkStatus;
|
||||||
|
#else
|
||||||
|
import net.minecraft.world.level.chunk.status.ChunkStatus;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
public final class StepStructureReference
|
public final class StepStructureReference
|
||||||
{
|
{
|
||||||
private static final ChunkStatus STATUS = ChunkStatus.STRUCTURE_REFERENCES;
|
private static final ChunkStatus STATUS = ChunkStatus.STRUCTURE_REFERENCES;
|
||||||
@@ -50,15 +54,26 @@ public final class StepStructureReference
|
|||||||
List<ChunkWrapper> chunkWrappers)
|
List<ChunkWrapper> chunkWrappers)
|
||||||
{
|
{
|
||||||
|
|
||||||
ArrayList<ChunkAccess> chunksToDo = new ArrayList<ChunkAccess>();
|
ArrayList<ChunkAccess> chunksToDo = new ArrayList<>();
|
||||||
|
|
||||||
for (ChunkWrapper chunkWrapper : chunkWrappers)
|
for (ChunkWrapper chunkWrapper : chunkWrappers)
|
||||||
{
|
{
|
||||||
ChunkAccess chunk = chunkWrapper.getChunk();
|
ChunkAccess chunk = chunkWrapper.getChunk();
|
||||||
if (chunk.getStatus().isOrAfter(STATUS)) continue;
|
if (chunkWrapper.getStatus().isOrAfter(STATUS))
|
||||||
|
{
|
||||||
|
// this chunk has already generated this step
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if (chunk instanceof ProtoChunk)
|
||||||
|
{
|
||||||
|
#if MC_VER < MC_1_21
|
||||||
((ProtoChunk) chunk).setStatus(STATUS);
|
((ProtoChunk) chunk).setStatus(STATUS);
|
||||||
|
#else
|
||||||
|
((ProtoChunk) chunk).setPersistedStatus(STATUS);
|
||||||
|
#endif
|
||||||
chunksToDo.add(chunk);
|
chunksToDo.add(chunk);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (ChunkAccess chunk : chunksToDo)
|
for (ChunkAccess chunk : chunksToDo)
|
||||||
{
|
{
|
||||||
|
|||||||
+25
-10
@@ -30,10 +30,16 @@ import com.seibel.distanthorizons.common.wrappers.worldGeneration.ThreadedParame
|
|||||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||||
import net.minecraft.server.level.WorldGenRegion;
|
import net.minecraft.server.level.WorldGenRegion;
|
||||||
import net.minecraft.world.level.chunk.ChunkAccess;
|
import net.minecraft.world.level.chunk.ChunkAccess;
|
||||||
import net.minecraft.world.level.chunk.ChunkStatus;
|
|
||||||
import net.minecraft.world.level.chunk.ProtoChunk;
|
import net.minecraft.world.level.chunk.ProtoChunk;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
|
#if MC_VER <= MC_1_20_4
|
||||||
|
import net.minecraft.world.level.chunk.ChunkStatus;
|
||||||
|
#else
|
||||||
|
import net.minecraft.world.level.chunk.status.ChunkStatus;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
public final class StepStructureStart
|
public final class StepStructureStart
|
||||||
{
|
{
|
||||||
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
|
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
|
||||||
@@ -70,20 +76,29 @@ public final class StepStructureStart
|
|||||||
for (ChunkWrapper chunkWrapper : chunkWrappers)
|
for (ChunkWrapper chunkWrapper : chunkWrappers)
|
||||||
{
|
{
|
||||||
ChunkAccess chunk = chunkWrapper.getChunk();
|
ChunkAccess chunk = chunkWrapper.getChunk();
|
||||||
if (!chunk.getStatus().isOrAfter(STATUS))
|
if (chunkWrapper.getStatus().isOrAfter(STATUS))
|
||||||
{
|
{
|
||||||
|
// this chunk has already generated this step
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if (chunk instanceof ProtoChunk)
|
||||||
|
{
|
||||||
|
#if MC_VER < MC_1_21
|
||||||
((ProtoChunk) chunk).setStatus(STATUS);
|
((ProtoChunk) chunk).setStatus(STATUS);
|
||||||
|
#else
|
||||||
|
((ProtoChunk) chunk).setPersistedStatus(STATUS);
|
||||||
|
#endif
|
||||||
chunksToDo.add(chunk);
|
chunksToDo.add(chunk);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if PRE_MC_1_19_2
|
#if MC_VER < MC_1_19_2
|
||||||
if (environment.params.worldGenSettings.generateFeatures())
|
if (this.environment.params.worldGenSettings.generateFeatures())
|
||||||
{
|
{
|
||||||
#elif PRE_MC_1_19_4
|
#elif MC_VER < MC_1_19_4
|
||||||
if (environment.params.worldGenSettings.generateStructures()) {
|
if (this.environment.params.worldGenSettings.generateStructures()) {
|
||||||
#else
|
#else
|
||||||
if (environment.params.worldOptions.generateStructures())
|
if (this.environment.params.worldOptions.generateStructures())
|
||||||
{
|
{
|
||||||
#endif
|
#endif
|
||||||
for (ChunkAccess chunk : chunksToDo)
|
for (ChunkAccess chunk : chunksToDo)
|
||||||
@@ -98,10 +113,10 @@ public final class StepStructureStart
|
|||||||
// and should prevent some concurrency issues
|
// and should prevent some concurrency issues
|
||||||
STRUCTURE_PLACEMENT_LOCK.lock();
|
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.generator.createStructures(environment.params.registry, tParams.structFeat, chunk, environment.params.structures,
|
||||||
environment.params.worldSeed);
|
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.generator.createStructures(environment.params.registry, environment.params.randomState, tParams.structFeat, chunk, environment.params.structures,
|
||||||
environment.params.worldSeed);
|
environment.params.worldSeed);
|
||||||
#else
|
#else
|
||||||
@@ -110,7 +125,7 @@ public final class StepStructureStart
|
|||||||
tParams.structFeat, chunk, environment.params.structures);
|
tParams.structFeat, chunk, environment.params.structures);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if POST_MC_1_18_2
|
#if MC_VER >= MC_1_18_2
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
tParams.structCheck.onStructureLoad(chunk.getPos(), chunk.getAllStarts());
|
tParams.structCheck.onStructureLoad(chunk.getPos(), chunk.getAllStarts());
|
||||||
|
|||||||
+22
-5
@@ -28,9 +28,14 @@ import com.seibel.distanthorizons.common.wrappers.worldGeneration.ThreadedParame
|
|||||||
|
|
||||||
import net.minecraft.server.level.WorldGenRegion;
|
import net.minecraft.server.level.WorldGenRegion;
|
||||||
import net.minecraft.world.level.chunk.ChunkAccess;
|
import net.minecraft.world.level.chunk.ChunkAccess;
|
||||||
import net.minecraft.world.level.chunk.ChunkStatus;
|
|
||||||
import net.minecraft.world.level.chunk.ProtoChunk;
|
import net.minecraft.world.level.chunk.ProtoChunk;
|
||||||
import net.minecraft.world.level.levelgen.Heightmap;
|
|
||||||
|
#if MC_VER <= MC_1_20_4
|
||||||
|
import net.minecraft.world.level.chunk.ChunkStatus;
|
||||||
|
#else
|
||||||
|
import net.minecraft.world.level.chunk.status.ChunkStatus;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
public final class StepSurface
|
public final class StepSurface
|
||||||
{
|
{
|
||||||
@@ -53,17 +58,29 @@ public final class StepSurface
|
|||||||
for (ChunkWrapper chunkWrapper : chunkWrappers)
|
for (ChunkWrapper chunkWrapper : chunkWrappers)
|
||||||
{
|
{
|
||||||
ChunkAccess chunk = chunkWrapper.getChunk();
|
ChunkAccess chunk = chunkWrapper.getChunk();
|
||||||
if (chunk.getStatus().isOrAfter(STATUS)) continue;
|
if (chunkWrapper.getStatus().isOrAfter(STATUS))
|
||||||
|
{
|
||||||
|
// this chunk has already generated this step
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if (chunk instanceof ProtoChunk)
|
||||||
|
{
|
||||||
|
#if MC_VER < MC_1_21
|
||||||
((ProtoChunk) chunk).setStatus(STATUS);
|
((ProtoChunk) chunk).setStatus(STATUS);
|
||||||
|
#else
|
||||||
|
((ProtoChunk) chunk).setPersistedStatus(STATUS);
|
||||||
|
#endif
|
||||||
|
|
||||||
chunksToDo.add(chunk);
|
chunksToDo.add(chunk);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (ChunkAccess chunk : chunksToDo)
|
for (ChunkAccess chunk : chunksToDo)
|
||||||
{
|
{
|
||||||
// System.out.println("StepSurface: "+chunk.getPos());
|
// 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);
|
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);
|
environment.params.generator.buildSurface(worldGenRegion, tParams.structFeat.forWorldGenRegion(worldGenRegion), chunk);
|
||||||
#else
|
#else
|
||||||
environment.params.generator.buildSurface(worldGenRegion, tParams.structFeat.forWorldGenRegion(worldGenRegion), environment.params.randomState, chunk);
|
environment.params.generator.buildSurface(worldGenRegion, tParams.structFeat.forWorldGenRegion(worldGenRegion), environment.params.randomState, chunk);
|
||||||
|
|||||||
@@ -0,0 +1,46 @@
|
|||||||
|
accessWidener v1 named
|
||||||
|
|
||||||
|
# used when determining where to save files to
|
||||||
|
accessible field net/minecraft/world/level/storage/DimensionDataStorage dataFolder Ljava/io/File;
|
||||||
|
|
||||||
|
# used when rendering
|
||||||
|
accessible method net/minecraft/client/renderer/GameRenderer getFov (Lnet/minecraft/client/Camera;FZ)D
|
||||||
|
|
||||||
|
# used for grabbing vanilla rendered chunks
|
||||||
|
accessible field net/minecraft/client/renderer/LevelRenderer visibleSections Lit/unimi/dsi/fastutil/objects/ObjectArrayList;
|
||||||
|
|
||||||
|
#accessible method net/minecraft/client/renderer/LevelRenderer renderSectionLayer (Lnet/minecraft/client/renderer/RenderType;Lcom/mojang/blaze3d/vertex/PoseStack;DDDLorg/joml/Matrix4f;)V
|
||||||
|
|
||||||
|
# world generation
|
||||||
|
# accessible method net/minecraft/world/level/lighting/LayerLightEngine queueSectionData (JLnet/minecraft/world/level/chunk/DataLayer;Z)V
|
||||||
|
accessible field net/minecraft/world/level/chunk/LevelChunk loaded Z
|
||||||
|
accessible field net/minecraft/world/level/lighting/LightEngine storage Lnet/minecraft/world/level/lighting/LayerLightSectionStorage;
|
||||||
|
accessible method net/minecraft/world/level/lighting/LayerLightSectionStorage lightOnInSection (J)Z
|
||||||
|
|
||||||
|
# lod generation from save file
|
||||||
|
accessible field net/minecraft/world/level/chunk/storage/ChunkStorage worker Lnet/minecraft/world/level/chunk/storage/IOWorker;
|
||||||
|
accessible field net/minecraft/world/level/chunk/storage/IOWorker storage Lnet/minecraft/world/level/chunk/storage/RegionFileStorage;
|
||||||
|
accessible field net/minecraft/world/level/chunk/storage/RegionFileStorage regionCache Lit/unimi/dsi/fastutil/longs/Long2ObjectLinkedOpenHashMap;
|
||||||
|
accessible field net/minecraft/world/level/chunk/storage/RegionFileStorage folder Ljava/nio/file/Path;
|
||||||
|
|
||||||
|
# grabbing textures
|
||||||
|
accessible class net/minecraft/client/renderer/texture/SpriteContents$AnimatedTexture
|
||||||
|
accessible method net/minecraft/client/renderer/texture/SpriteContents$AnimatedTexture getFrameX (I)I
|
||||||
|
accessible method net/minecraft/client/renderer/texture/SpriteContents$AnimatedTexture getFrameY (I)I
|
||||||
|
accessible field net/minecraft/client/renderer/texture/SpriteContents animatedTexture Lnet/minecraft/client/renderer/texture/SpriteContents$AnimatedTexture;
|
||||||
|
accessible field net/minecraft/client/renderer/texture/SpriteContents originalImage Lcom/mojang/blaze3d/platform/NativeImage;
|
||||||
|
|
||||||
|
# UI stuff
|
||||||
|
accessible field net/minecraft/client/gui/components/AbstractButton SPRITES Lnet/minecraft/client/gui/components/WidgetSprites;
|
||||||
|
# Handles inserting the config button
|
||||||
|
accessible field net/minecraft/client/gui/layouts/HeaderAndFooterLayout headerFrame Lnet/minecraft/client/gui/layouts/FrameLayout;
|
||||||
|
accessible field net/minecraft/client/gui/layouts/FrameLayout children Ljava/util/List;
|
||||||
|
accessible class net/minecraft/client/gui/layouts/FrameLayout$ChildContainer
|
||||||
|
accessible field net/minecraft/client/gui/layouts/LinearLayout wrapped Lnet/minecraft/client/gui/layouts/GridLayout;
|
||||||
|
|
||||||
|
# hacky stuff
|
||||||
|
accessible field net/minecraft/util/ThreadingDetector lock Ljava/util/concurrent/Semaphore;
|
||||||
|
mutable field net/minecraft/util/ThreadingDetector lock Ljava/util/concurrent/Semaphore;
|
||||||
|
accessible field net/minecraft/client/gui/components/AbstractSelectionList scrollAmount D # Hack to bypass vanilla's setScrollAmount's clamp
|
||||||
|
|
||||||
|
|
||||||
+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.
|
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: \
|
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: \
|
2. Set up your dev environment: \
|
||||||
`./gradlew build`
|
`./gradlew build`
|
||||||
@@ -37,13 +37,13 @@ Contributions to this project are under the [lesser GPL v3 license](LICENSE.txt)
|
|||||||
`./gradlew fabric:runClient` \
|
`./gradlew fabric:runClient` \
|
||||||
When running the game, load or generate a world to confirm Distant Horizons initializes correctly.
|
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
|
## 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.
|
* 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.
|
* Open a merge request to: fix bugs, fix documentations, improve an existing system, or complete a feature.
|
||||||
* When contributing:
|
* When contributing:
|
||||||
|
|||||||
+1
-1
Submodule coreSubProjects updated: f32e25f52f...f767215ff0
+23
-23
@@ -1,5 +1,5 @@
|
|||||||
plugins {
|
plugins {
|
||||||
id "fabric-loom" version "1.1.+"
|
id "fabric-loom" version "1.6-SNAPSHOT"
|
||||||
}
|
}
|
||||||
|
|
||||||
loom {
|
loom {
|
||||||
@@ -23,11 +23,11 @@ loom {
|
|||||||
}
|
}
|
||||||
|
|
||||||
remapJar {
|
remapJar {
|
||||||
inputFile = shadowJar.archiveFile
|
inputFile = shadeDowngradedApi.archiveFile
|
||||||
dependsOn shadowJar
|
dependsOn shadeDowngradedApi
|
||||||
classifier null
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
configurations {
|
configurations {
|
||||||
// The addModJar basically embeds the mod to the built jar
|
// The addModJar basically embeds the mod to the built jar
|
||||||
addModJar
|
addModJar
|
||||||
@@ -35,6 +35,8 @@ configurations {
|
|||||||
modImplementation.extendsFrom addModJar
|
modImplementation.extendsFrom addModJar
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def addMod(path, enabled) {
|
def addMod(path, enabled) {
|
||||||
if (enabled == "2")
|
if (enabled == "2")
|
||||||
dependencies { modImplementation(path) }
|
dependencies { modImplementation(path) }
|
||||||
@@ -43,7 +45,7 @@ def addMod(path, enabled) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
minecraft "com.mojang:minecraft:${minecraft_version}"
|
minecraft "com.mojang:minecraft:${rootProject.minecraft_version}"
|
||||||
mappings loom.layered() {
|
mappings loom.layered() {
|
||||||
// Mojmap mappings
|
// Mojmap mappings
|
||||||
officialMojangMappings()
|
officialMojangMappings()
|
||||||
@@ -53,6 +55,13 @@ dependencies {
|
|||||||
// Fabric loader
|
// Fabric loader
|
||||||
modImplementation "net.fabricmc:fabric-loader:${rootProject.fabric_loader_version}"
|
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
|
// Fabric API
|
||||||
addModJar(fabricApi.module("fabric-api-base", rootProject.fabric_api_version))
|
addModJar(fabricApi.module("fabric-api-base", rootProject.fabric_api_version))
|
||||||
addModJar(fabricApi.module("fabric-lifecycle-events-v1", rootProject.fabric_api_version))
|
addModJar(fabricApi.module("fabric-lifecycle-events-v1", rootProject.fabric_api_version))
|
||||||
@@ -61,11 +70,14 @@ dependencies {
|
|||||||
addModJar(fabricApi.module("fabric-rendering-v1", rootProject.fabric_api_version)) // TODO: Remove this as it is only needed in 1 line (FabricClientProxy)
|
addModJar(fabricApi.module("fabric-rendering-v1", rootProject.fabric_api_version)) // 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.module("fabric-networking-api-v1", rootProject.fabric_api_version))
|
||||||
|
|
||||||
|
// used by mod menu in MC 1.20.6+
|
||||||
|
addModJar(fabricApi.module("fabric-screen-api-v1", rootProject.fabric_api_version))
|
||||||
|
addModJar(fabricApi.module("fabric-key-binding-api-v1", rootProject.fabric_api_version))
|
||||||
|
|
||||||
|
|
||||||
// Mod Menu
|
// Mod Menu
|
||||||
modImplementation("com.terraformersmc:modmenu:${rootProject.modmenu_version}")
|
modImplementation("com.terraformersmc:modmenu:${rootProject.modmenu_version}")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Starlight
|
// Starlight
|
||||||
addMod("curse.maven:starlight-521783:${rootProject.starlight_version_fabric}", rootProject.enable_starlight)
|
addMod("curse.maven:starlight-521783:${rootProject.starlight_version_fabric}", rootProject.enable_starlight)
|
||||||
|
|
||||||
@@ -93,8 +105,9 @@ dependencies {
|
|||||||
addMod("io.vram:canvas-fabric-${project.canvas_version}", rootProject.enable_canvas)
|
addMod("io.vram:canvas-fabric-${project.canvas_version}", rootProject.enable_canvas)
|
||||||
|
|
||||||
// Immersive Portals
|
// Immersive Portals
|
||||||
if (rootProject.enable_immersive_portals == "1")
|
if (rootProject.enable_immersive_portals == "1") {
|
||||||
modCompileOnly ("com.github.iPortalTeam.ImmersivePortalsMod:imm_ptl_core:${project.immersive_portals_version}")
|
modCompileOnly("com.github.iPortalTeam.ImmersivePortalsMod:imm_ptl_core:${project.immersive_portals_version}")
|
||||||
|
}
|
||||||
else if (rootProject.enable_immersive_portals == "2") {
|
else if (rootProject.enable_immersive_portals == "2") {
|
||||||
modImplementation ("com.github.iPortalTeam.ImmersivePortalsMod:imm_ptl_core:${project.immersive_portals_version}") {
|
modImplementation ("com.github.iPortalTeam.ImmersivePortalsMod:imm_ptl_core:${project.immersive_portals_version}") {
|
||||||
exclude(group: "net.fabricmc.fabric-api")
|
exclude(group: "net.fabricmc.fabric-api")
|
||||||
@@ -127,26 +140,13 @@ processResources {
|
|||||||
runClient {
|
runClient {
|
||||||
dependsOn(copyCoreResources)
|
dependsOn(copyCoreResources)
|
||||||
dependsOn(copyCommonLoaderResources)
|
dependsOn(copyCommonLoaderResources)
|
||||||
jvmArgs([ "-XX:-OmitStackTraceInFastThrow", minecraftMemoryJavaArg ])
|
// jvmArgs([ "-XX:-OmitStackTraceInFastThrow", minecraftMemoryJavaArg ])
|
||||||
finalizedBy(deleteResources)
|
finalizedBy(deleteResources)
|
||||||
}
|
}
|
||||||
|
|
||||||
//jar {
|
|
||||||
// classifier "dev"
|
|
||||||
//}
|
|
||||||
|
|
||||||
sourcesJar {
|
sourcesJar {
|
||||||
def commonSources = project(":common").sourcesJar
|
def commonSources = project(":common").sourcesJar
|
||||||
dependsOn commonSources
|
dependsOn commonSources
|
||||||
from commonSources.archiveFile.map { zipTree(it) }
|
from commonSources.archiveFile.map { zipTree(it) }
|
||||||
|
|
||||||
// def fabricLikeSources = project(":fabricLike").sourcesJar
|
|
||||||
// dependsOn fabricLikeSources
|
|
||||||
// from fabricLikeSources.archiveFile.map { zipTree(it) }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//components.java {
|
|
||||||
// withVariantsFromConfiguration(project.configurations.shadowRuntimeElements) {
|
|
||||||
// skip()
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
@@ -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,7 +19,9 @@
|
|||||||
|
|
||||||
package com.seibel.distanthorizons.fabric;
|
package com.seibel.distanthorizons.fabric;
|
||||||
|
|
||||||
import com.seibel.distanthorizons.common.rendering.SeamlessOverdraw;
|
import com.mojang.blaze3d.systems.RenderSystem;
|
||||||
|
import com.mojang.blaze3d.vertex.PoseStack;
|
||||||
|
import com.seibel.distanthorizons.common.AbstractModInitializer;
|
||||||
import com.seibel.distanthorizons.common.wrappers.McObjectConverter;
|
import com.seibel.distanthorizons.common.wrappers.McObjectConverter;
|
||||||
import com.seibel.distanthorizons.common.wrappers.world.ClientLevelWrapper;
|
import com.seibel.distanthorizons.common.wrappers.world.ClientLevelWrapper;
|
||||||
import com.seibel.distanthorizons.core.api.internal.ClientApi;
|
import com.seibel.distanthorizons.core.api.internal.ClientApi;
|
||||||
@@ -27,41 +29,39 @@ import com.mojang.blaze3d.platform.InputConstants;
|
|||||||
import com.seibel.distanthorizons.common.wrappers.chunk.ChunkWrapper;
|
import com.seibel.distanthorizons.common.wrappers.chunk.ChunkWrapper;
|
||||||
|
|
||||||
import com.seibel.distanthorizons.core.api.internal.SharedApi;
|
import com.seibel.distanthorizons.core.api.internal.SharedApi;
|
||||||
import com.seibel.distanthorizons.core.config.Config;
|
|
||||||
import com.seibel.distanthorizons.core.dependencyInjection.ModAccessorInjector;
|
import com.seibel.distanthorizons.core.dependencyInjection.ModAccessorInjector;
|
||||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||||
|
import com.seibel.distanthorizons.core.util.threading.ThreadPoolUtil;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.ISodiumAccessor;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.ISodiumAccessor;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
|
||||||
import com.seibel.distanthorizons.coreapi.ModInfo;
|
import com.seibel.distanthorizons.core.util.math.Mat4f;
|
||||||
import com.seibel.distanthorizons.fabric.wrappers.modAccessor.SodiumAccessor;
|
import com.seibel.distanthorizons.fabric.wrappers.modAccessor.SodiumAccessor;
|
||||||
//import io.netty.buffer.ByteBuf;
|
//import io.netty.buffer.ByteBuf;
|
||||||
import net.fabricmc.api.EnvType;
|
import net.fabricmc.api.EnvType;
|
||||||
import net.fabricmc.api.Environment;
|
import net.fabricmc.api.Environment;
|
||||||
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientChunkEvents;
|
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientChunkEvents;
|
||||||
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
|
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
|
||||||
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking;
|
|
||||||
import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderEvents;
|
import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderEvents;
|
||||||
import net.fabricmc.fabric.api.event.player.AttackBlockCallback;
|
import net.fabricmc.fabric.api.event.player.AttackBlockCallback;
|
||||||
import net.fabricmc.fabric.api.event.player.UseBlockCallback;
|
import net.fabricmc.fabric.api.event.player.UseBlockCallback;
|
||||||
import net.fabricmc.fabric.api.networking.v1.PacketSender;
|
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.gui.screens.TitleScreen;
|
import net.minecraft.client.gui.screens.TitleScreen;
|
||||||
|
|
||||||
|
#if MC_VER < MC_1_19_4
|
||||||
import java.nio.FloatBuffer;
|
import java.nio.FloatBuffer;
|
||||||
|
#endif
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
import java.util.concurrent.ThreadPoolExecutor;
|
||||||
|
|
||||||
import net.minecraft.client.multiplayer.ClientLevel;
|
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.InteractionResult;
|
||||||
import net.minecraft.world.level.chunk.ChunkAccess;
|
import net.minecraft.world.level.chunk.ChunkAccess;
|
||||||
import net.minecraft.world.phys.HitResult;
|
import net.minecraft.world.phys.HitResult;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.joml.Matrix4f;
|
||||||
import org.lwjgl.glfw.GLFW;
|
import org.lwjgl.glfw.GLFW;
|
||||||
import org.lwjgl.opengl.GL15;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This handles all events sent to the client,
|
* This handles all events sent to the client,
|
||||||
@@ -72,7 +72,7 @@ import org.lwjgl.opengl.GL15;
|
|||||||
* @version 2023-7-27
|
* @version 2023-7-27
|
||||||
*/
|
*/
|
||||||
@Environment(EnvType.CLIENT)
|
@Environment(EnvType.CLIENT)
|
||||||
public class FabricClientProxy
|
public class FabricClientProxy implements AbstractModInitializer.IEventProxy
|
||||||
{
|
{
|
||||||
private final ClientApi clientApi = ClientApi.INSTANCE;
|
private final ClientApi clientApi = ClientApi.INSTANCE;
|
||||||
private static final IMinecraftClientWrapper MC = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class);
|
private static final IMinecraftClientWrapper MC = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class);
|
||||||
@@ -106,7 +106,7 @@ public class FabricClientProxy
|
|||||||
// tick events //
|
// tick events //
|
||||||
//=============//
|
//=============//
|
||||||
|
|
||||||
ClientTickEvents.START_CLIENT_TICK.register((client) -> { ClientApi.INSTANCE.clientTickEvent(); });
|
ClientTickEvents.START_CLIENT_TICK.register((client) -> ClientApi.INSTANCE.clientTickEvent());
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -122,16 +122,26 @@ public class FabricClientProxy
|
|||||||
});
|
});
|
||||||
|
|
||||||
// (kinda) block break event
|
// (kinda) block break event
|
||||||
|
// Since fabric doesn't have a client-side break-block API event, this is the next best thing
|
||||||
AttackBlockCallback.EVENT.register((player, level, interactionHand, blockPos, direction) ->
|
AttackBlockCallback.EVENT.register((player, level, interactionHand, blockPos, direction) ->
|
||||||
{
|
{
|
||||||
// if we have access to the server, use the chunk save event instead
|
// if we have access to the server, use the chunk save event instead
|
||||||
if (MC.clientConnectedToDedicatedServer())
|
if (MC.clientConnectedToDedicatedServer())
|
||||||
{
|
{
|
||||||
// Since fabric doesn't have a client-side break-block API event, this is the next best thing
|
if (SharedApi.isChunkAtBlockPosAlreadyUpdating(blockPos.getX(), blockPos.getZ()))
|
||||||
|
{
|
||||||
|
// executor to prevent locking up the render/event thread
|
||||||
|
// if the getChunk() takes longer than expected
|
||||||
|
// (which can be caused by certain mods)
|
||||||
|
ThreadPoolExecutor executor = ThreadPoolUtil.getFileHandlerExecutor();
|
||||||
|
if (executor != null)
|
||||||
|
{
|
||||||
|
executor.execute(() ->
|
||||||
|
{
|
||||||
ChunkAccess chunk = level.getChunk(blockPos);
|
ChunkAccess chunk = level.getChunk(blockPos);
|
||||||
if (chunk != null)
|
if (chunk != null)
|
||||||
{
|
{
|
||||||
LOGGER.trace("attack block at blockPos: " + blockPos);
|
//LOGGER.trace("attack block at blockPos: " + blockPos);
|
||||||
|
|
||||||
IClientLevelWrapper wrappedLevel = ClientLevelWrapper.getWrapper((ClientLevel) level);
|
IClientLevelWrapper wrappedLevel = ClientLevelWrapper.getWrapper((ClientLevel) level);
|
||||||
SharedApi.INSTANCE.chunkBlockChangedEvent(
|
SharedApi.INSTANCE.chunkBlockChangedEvent(
|
||||||
@@ -139,6 +149,9 @@ public class FabricClientProxy
|
|||||||
wrappedLevel
|
wrappedLevel
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// don't stop the callback
|
// don't stop the callback
|
||||||
@@ -146,19 +159,29 @@ public class FabricClientProxy
|
|||||||
});
|
});
|
||||||
|
|
||||||
// (kinda) block place event
|
// (kinda) block place event
|
||||||
|
// Since fabric doesn't have a client-side place-block API event, this is the next best thing
|
||||||
UseBlockCallback.EVENT.register((player, level, hand, hitResult) ->
|
UseBlockCallback.EVENT.register((player, level, hand, hitResult) ->
|
||||||
{
|
{
|
||||||
// if we have access to the server, use the chunk save event instead
|
// if we have access to the server, use the chunk save event instead
|
||||||
if (MC.clientConnectedToDedicatedServer())
|
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
|
if (hitResult.getType() == HitResult.Type.BLOCK
|
||||||
&& !hitResult.isInside())
|
&& !hitResult.isInside())
|
||||||
|
{
|
||||||
|
if (SharedApi.isChunkAtBlockPosAlreadyUpdating(hitResult.getBlockPos().getX(), hitResult.getBlockPos().getZ()))
|
||||||
|
{
|
||||||
|
// executor to prevent locking up the render/event thread
|
||||||
|
// if the getChunk() takes longer than expected
|
||||||
|
// (which can be caused by certain mods)
|
||||||
|
ThreadPoolExecutor executor = ThreadPoolUtil.getFileHandlerExecutor();
|
||||||
|
if (executor != null)
|
||||||
|
{
|
||||||
|
executor.execute(() ->
|
||||||
{
|
{
|
||||||
ChunkAccess chunk = level.getChunk(hitResult.getBlockPos());
|
ChunkAccess chunk = level.getChunk(hitResult.getBlockPos());
|
||||||
if (chunk != null)
|
if (chunk != null)
|
||||||
{
|
{
|
||||||
LOGGER.trace("use block at blockPos: " + hitResult.getBlockPos());
|
//LOGGER.trace("use block at blockPos: " + hitResult.getBlockPos());
|
||||||
|
|
||||||
IClientLevelWrapper wrappedLevel = ClientLevelWrapper.getWrapper((ClientLevel) level);
|
IClientLevelWrapper wrappedLevel = ClientLevelWrapper.getWrapper((ClientLevel) level);
|
||||||
SharedApi.INSTANCE.chunkBlockChangedEvent(
|
SharedApi.INSTANCE.chunkBlockChangedEvent(
|
||||||
@@ -166,6 +189,9 @@ public class FabricClientProxy
|
|||||||
wrappedLevel
|
wrappedLevel
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -187,30 +213,26 @@ public class FabricClientProxy
|
|||||||
// render event //
|
// 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) ->
|
WorldRenderEvents.AFTER_SETUP.register((renderContext) ->
|
||||||
{
|
{
|
||||||
this.clientApi.renderLods(ClientLevelWrapper.getWrapper(renderContext.world()),
|
Mat4f projectionMatrix = McObjectConverter.Convert(renderContext.projectionMatrix());
|
||||||
McObjectConverter.Convert(renderContext.matrixStack().last().pose()),
|
|
||||||
McObjectConverter.Convert(renderContext.projectionMatrix()),
|
|
||||||
renderContext.tickDelta());
|
|
||||||
|
|
||||||
|
Mat4f modelViewMatrix;
|
||||||
// experimental proof-of-concept option
|
#if MC_VER < MC_1_20_6
|
||||||
if (Config.Client.Advanced.Graphics.AdvancedGraphics.seamlessOverdraw.get())
|
modelViewMatrix = McObjectConverter.Convert(renderContext.matrixStack().last().pose());
|
||||||
{
|
|
||||||
float[] matrixFloatArray = SeamlessOverdraw.overwriteMinecraftNearFarClipPlanes(renderContext.projectionMatrix(), renderContext.tickDelta());
|
|
||||||
|
|
||||||
#if MC_1_16_5
|
|
||||||
SeamlessOverdraw.applyLegacyProjectionMatrix(matrixFloatArray);
|
|
||||||
#elif PRE_MC_1_19_4
|
|
||||||
renderContext.projectionMatrix().load(FloatBuffer.wrap(matrixFloatArray));
|
|
||||||
#else
|
#else
|
||||||
renderContext.projectionMatrix().set(matrixFloatArray);
|
modelViewMatrix = McObjectConverter.Convert(renderContext.positionMatrix());
|
||||||
#endif
|
#endif
|
||||||
}
|
|
||||||
|
this.clientApi.renderLods(ClientLevelWrapper.getWrapper(renderContext.world()),
|
||||||
|
modelViewMatrix,
|
||||||
|
projectionMatrix,
|
||||||
|
#if MC_VER < MC_1_21
|
||||||
|
renderContext.tickDelta()
|
||||||
|
#else
|
||||||
|
renderContext.tickCounter().getGameTimeDeltaTicks()
|
||||||
|
#endif
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Debug keyboard event
|
// Debug keyboard event
|
||||||
|
|||||||
@@ -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,73 +19,56 @@
|
|||||||
|
|
||||||
package com.seibel.distanthorizons.fabric;
|
package com.seibel.distanthorizons.fabric;
|
||||||
|
|
||||||
import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiAfterDhInitEvent;
|
import com.mojang.brigadier.CommandDispatcher;
|
||||||
import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiBeforeDhInitEvent;
|
import com.seibel.distanthorizons.common.AbstractModInitializer;
|
||||||
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.seibel.distanthorizons.core.config.Config;
|
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.ModAccessorInjector;
|
||||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||||
import com.seibel.distanthorizons.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 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 org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
|
import java.awt.*;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize and setup the Mod. <br>
|
* Initialize and setup the Mod. <br>
|
||||||
* If you are looking for the real start of the mod
|
* If you are looking for the real start of the mod
|
||||||
* check out the ClientProxy.
|
* 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 ResourceLocation INITIAL_PHASE = ResourceLocation.tryParse("distanthorizons:dedicated_server_initial");
|
||||||
|
|
||||||
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
|
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
|
||||||
|
|
||||||
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);
|
IModChecker modChecker = SingletonInjector.INSTANCE.get(IModChecker.class);
|
||||||
if (modChecker.isModLoaded("sodium"))
|
if (modChecker.isModLoaded("sodium"))
|
||||||
{
|
{
|
||||||
@@ -94,10 +77,13 @@ public class FabricMain
|
|||||||
// If sodium is installed Indium is also necessary in order to use the Fabric rendering API
|
// If sodium is installed Indium is also necessary in order to use the Fabric rendering API
|
||||||
if (!modChecker.isModLoaded("indium"))
|
if (!modChecker.isModLoaded("indium"))
|
||||||
{
|
{
|
||||||
// People don't read the crash logs!!!
|
String indiumMissingMessage = ModInfo.READABLE_NAME + " needs Indium to work with Sodium.\nPlease download Indium from https://modrinth.com/mod/indium";
|
||||||
// So, just put a notification, so they hopefully realise what's the problem (and dont just open issues)
|
LOGGER.fatal(indiumMissingMessage);
|
||||||
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);
|
if (!GraphicsEnvironment.isHeadless())
|
||||||
|
{
|
||||||
|
JOptionPane.showMessageDialog(null, indiumMissingMessage, ModInfo.READABLE_NAME, JOptionPane.INFORMATION_MESSAGE);
|
||||||
|
}
|
||||||
|
|
||||||
IMinecraftClientWrapper mc = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class);
|
IMinecraftClientWrapper mc = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class);
|
||||||
String errorMessage = "loading Distant Horizons. Distant Horizons requires Indium in order to run with Sodium.";
|
String errorMessage = "loading Distant Horizons. Distant Horizons requires Indium in order to run with Sodium.";
|
||||||
@@ -105,30 +91,44 @@ public class FabricMain
|
|||||||
mc.crashMinecraft(errorMessage, new Exception(exceptionError));
|
mc.crashMinecraft(errorMessage, new Exception(exceptionError));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (modChecker.isModLoaded("starlight"))
|
|
||||||
{
|
this.tryCreateModCompatAccessor("starlight", IStarlightAccessor.class, StarlightAccessor::new);
|
||||||
ModAccessorInjector.INSTANCE.bind(IStarlightAccessor.class, new StarlightAccessor());
|
this.tryCreateModCompatAccessor("optifine", IOptifineAccessor.class, OptifineAccessor::new);
|
||||||
}
|
this.tryCreateModCompatAccessor("bclib", IBCLibAccessor.class, BCLibAccessor::new);
|
||||||
if (modChecker.isModLoaded("optifine"))
|
#if MC_VER >= MC_1_19_4
|
||||||
{
|
// 1.19.4 is the lowest version Iris supports DH
|
||||||
ModAccessorInjector.INSTANCE.bind(IOptifineAccessor.class, new OptifineAccessor());
|
this.tryCreateModCompatAccessor("iris", IIrisAccessor.class, IrisAccessor::new);
|
||||||
}
|
#endif
|
||||||
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
|
@Override
|
||||||
// 1.17.1 won't support this since there isn't a matching Iris version
|
protected void subscribeRegisterCommandsEvent(Consumer<CommandDispatcher<CommandSourceStack>> eventHandler) { }
|
||||||
if (modChecker.isModLoaded("iris"))
|
|
||||||
|
@Override
|
||||||
|
protected void subscribeClientStartedEvent(Runnable eventHandler) { ClientLifecycleEvents.CLIENT_STARTED.register((mc) -> eventHandler.run()); }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void subscribeServerStartingEvent(Consumer<MinecraftServer> eventHandler)
|
||||||
{
|
{
|
||||||
ModAccessorInjector.INSTANCE.bind(IIrisAccessor.class, new IrisAccessor());
|
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
|
#endif
|
||||||
|
|
||||||
LOGGER.info(ModInfo.READABLE_NAME + " Initialized");
|
if (ConfigBase.INSTANCE == null)
|
||||||
|
throw new IllegalStateException("Config was not initialized. Make sure to call LodCommonMain.initConfig() before calling this method.");
|
||||||
ApiEventInjector.INSTANCE.fireAllEvents(DhApiAfterDhInitEvent.class, null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
package com.seibel.distanthorizons.fabric;
|
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.chunk.ChunkWrapper;
|
||||||
import com.seibel.distanthorizons.common.wrappers.misc.ServerPlayerWrapper;
|
import com.seibel.distanthorizons.common.wrappers.misc.ServerPlayerWrapper;
|
||||||
import com.seibel.distanthorizons.common.wrappers.world.ClientLevelWrapper;
|
import com.seibel.distanthorizons.common.wrappers.world.ClientLevelWrapper;
|
||||||
import com.seibel.distanthorizons.common.wrappers.world.ServerLevelWrapper;
|
import com.seibel.distanthorizons.common.wrappers.world.ServerLevelWrapper;
|
||||||
import com.seibel.distanthorizons.common.wrappers.worldGeneration.BatchGenerationEnvironment;
|
import com.seibel.distanthorizons.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.api.internal.ServerApi;
|
||||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
|
||||||
@@ -32,7 +32,7 @@ import java.util.function.Supplier;
|
|||||||
* @author Tomlee
|
* @author Tomlee
|
||||||
* @version 5-11-2022
|
* @version 5-11-2022
|
||||||
*/
|
*/
|
||||||
public class FabricServerProxy
|
public class FabricServerProxy implements AbstractModInitializer.IEventProxy
|
||||||
{
|
{
|
||||||
private static final ServerApi SERVER_API = ServerApi.INSTANCE;
|
private static final ServerApi SERVER_API = ServerApi.INSTANCE;
|
||||||
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
|
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.ClientApi;
|
||||||
import com.seibel.distanthorizons.core.api.internal.SharedApi;
|
import com.seibel.distanthorizons.core.api.internal.SharedApi;
|
||||||
import net.minecraft.client.multiplayer.ClientLevel;
|
import net.minecraft.client.multiplayer.ClientLevel;
|
||||||
#if POST_MC_1_18_2
|
#if MC_VER >= MC_1_18_2
|
||||||
#endif
|
#endif
|
||||||
import net.minecraft.world.level.chunk.LevelChunk;
|
import net.minecraft.world.level.chunk.LevelChunk;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
@@ -44,14 +44,14 @@ public class MixinClientLevel
|
|||||||
// //Moved to MixinClientPacketListener
|
// //Moved to MixinClientPacketListener
|
||||||
// @Inject(method = "<init>", at = @At("TAIL"))
|
// @Inject(method = "<init>", at = @At("TAIL"))
|
||||||
// private void loadWorldEvent(ClientPacketListener clientPacketListener, ClientLevel.ClientLevelData clientLevelData, ResourceKey resourceKey,
|
// 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 MC_VER >= 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 int j, #endif Supplier supplier, LevelRenderer levelRenderer, boolean bl, long l, CallbackInfo ci)
|
||||||
// {
|
// {
|
||||||
// ClientApi.INSTANCE.clientLevelLoadEvent(WorldWrapper.getWorldWrapper((ClientLevel)(Object)this));
|
// ClientApi.INSTANCE.clientLevelLoadEvent(WorldWrapper.getWorldWrapper((ClientLevel)(Object)this));
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// Moved to overriding the enableChunkLight(...) method over at ClientPacketListener for 1.20+
|
// 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"))
|
@Inject(method = "setLightReady", at = @At("HEAD"))
|
||||||
private void onChunkLightReady(int x, int z, CallbackInfo ci)
|
private void onChunkLightReady(int x, int z, CallbackInfo ci)
|
||||||
{
|
{
|
||||||
|
|||||||
+22
-5
@@ -7,11 +7,12 @@ import net.minecraft.client.multiplayer.ClientLevel;
|
|||||||
import net.minecraft.client.multiplayer.ClientPacketListener;
|
import net.minecraft.client.multiplayer.ClientPacketListener;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
|
import org.spongepowered.asm.mixin.Unique;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
#if POST_MC_1_20_1
|
#if MC_VER >= MC_1_20_1
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
|
||||||
import net.minecraft.world.level.chunk.LevelChunk;
|
import net.minecraft.world.level.chunk.LevelChunk;
|
||||||
import com.seibel.distanthorizons.common.wrappers.chunk.ChunkWrapper;
|
import com.seibel.distanthorizons.common.wrappers.chunk.ChunkWrapper;
|
||||||
@@ -23,15 +24,31 @@ public class MixinClientPacketListener
|
|||||||
@Shadow
|
@Shadow
|
||||||
private ClientLevel level;
|
private ClientLevel level;
|
||||||
|
|
||||||
|
@Unique
|
||||||
|
private ClientLevel previousLevel;
|
||||||
|
|
||||||
|
|
||||||
@Inject(method = "handleLogin", at = @At("RETURN"))
|
@Inject(method = "handleLogin", at = @At("RETURN"))
|
||||||
void onHandleLoginEnd(CallbackInfo ci) { ClientApi.INSTANCE.onClientOnlyConnected(); }
|
void onHandleLoginEnd(CallbackInfo ci) { ClientApi.INSTANCE.onClientOnlyConnected(); }
|
||||||
|
|
||||||
@Inject(method = "handleRespawn", at = @At("HEAD"))
|
@Inject(method = "handleRespawn", at = @At("HEAD"))
|
||||||
void onHandleRespawnStart(CallbackInfo ci) { ClientApi.INSTANCE.clientLevelUnloadEvent(ClientLevelWrapper.getWrapper(this.level)); }
|
void onHandleRespawnStart(CallbackInfo ci) { this.previousLevel = this.level; }
|
||||||
@Inject(method = "handleRespawn", at = @At("RETURN"))
|
@Inject(method = "handleRespawn", at = @At("RETURN"))
|
||||||
void onHandleRespawnEnd(CallbackInfo ci) { ClientApi.INSTANCE.clientLevelLoadEvent(ClientLevelWrapper.getWrapper(this.level)); }
|
void onHandleRespawnEnd(CallbackInfo ci)
|
||||||
|
{
|
||||||
|
// If the player changes dimensions the "this.level" will be changed halfway through the respawn method.
|
||||||
|
// By checking if the object references are the same, we can see if the previous level should be unloaded
|
||||||
|
// or if the player just respawned in the same level.
|
||||||
|
if (this.previousLevel != this.level)
|
||||||
|
{
|
||||||
|
ClientApi.INSTANCE.clientLevelUnloadEvent(ClientLevelWrapper.getWrapper(this.previousLevel));
|
||||||
|
ClientApi.INSTANCE.clientLevelLoadEvent(ClientLevelWrapper.getWrapper(this.level));
|
||||||
|
}
|
||||||
|
|
||||||
#if PRE_MC_1_19_4
|
this.previousLevel = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if MC_VER < MC_1_19_4
|
||||||
@Inject(method = "cleanup", at = @At("HEAD"))
|
@Inject(method = "cleanup", at = @At("HEAD"))
|
||||||
#else
|
#else
|
||||||
@Inject(method = "close", at = @At("HEAD"))
|
@Inject(method = "close", at = @At("HEAD"))
|
||||||
@@ -45,7 +62,7 @@ public class MixinClientPacketListener
|
|||||||
ClientApi.INSTANCE.onClientOnlyDisconnected();
|
ClientApi.INSTANCE.onClientOnlyDisconnected();
|
||||||
}
|
}
|
||||||
|
|
||||||
#if POST_MC_1_20_1
|
#if MC_VER >= MC_1_20_1
|
||||||
@Inject(method = "enableChunkLight", at = @At("TAIL"))
|
@Inject(method = "enableChunkLight", at = @At("TAIL"))
|
||||||
void onEnableChunkLight(LevelChunk chunk, int x, int z, CallbackInfo ci)
|
void onEnableChunkLight(LevelChunk chunk, int x, int z, CallbackInfo ci)
|
||||||
{
|
{
|
||||||
|
|||||||
-69
@@ -1,69 +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.fabric.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.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 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 = "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 (!this.isLightTexture
|
|
||||||
|| mc == null
|
|
||||||
|| mc.getWrappedClientLevel() == null
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//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.effect.MobEffects;
|
||||||
import net.minecraft.world.entity.Entity;
|
import net.minecraft.world.entity.Entity;
|
||||||
import net.minecraft.world.entity.LivingEntity;
|
import net.minecraft.world.entity.LivingEntity;
|
||||||
#if PRE_MC_1_17_1
|
#if MC_VER < MC_1_17_1
|
||||||
import net.minecraft.world.level.material.FluidState;
|
import net.minecraft.world.level.material.FluidState;
|
||||||
#else
|
#else
|
||||||
import net.minecraft.world.level.material.FogType;
|
import net.minecraft.world.level.material.FogType;
|
||||||
@@ -50,14 +50,14 @@ public class MixinFogRenderer
|
|||||||
private static final float A_EVEN_LARGER_VALUE = 42069420694206942069.F;
|
private static final float A_EVEN_LARGER_VALUE = 42069420694206942069.F;
|
||||||
|
|
||||||
@Inject(at = @At("RETURN"), method = "setupFog")
|
@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)
|
private static void disableSetupFog(Camera camera, FogMode fogMode, float f, boolean bl, CallbackInfo callback)
|
||||||
{
|
{
|
||||||
#else
|
#else
|
||||||
private static void disableSetupFog(Camera camera, FogMode fogMode, float f, boolean bl, float g, CallbackInfo callback)
|
private static void disableSetupFog(Camera camera, FogMode fogMode, float f, boolean bl, float g, CallbackInfo callback)
|
||||||
{
|
{
|
||||||
#endif
|
#endif
|
||||||
#if PRE_MC_1_17_1
|
#if MC_VER < MC_1_17_1
|
||||||
FluidState fluidState = camera.getFluidInCamera();
|
FluidState fluidState = camera.getFluidInCamera();
|
||||||
boolean cameraNotInFluid = fluidState.isEmpty();
|
boolean cameraNotInFluid = fluidState.isEmpty();
|
||||||
#else
|
#else
|
||||||
@@ -71,7 +71,7 @@ public class MixinFogRenderer
|
|||||||
&& !SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class).isFogStateSpecial()
|
&& !SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class).isFogStateSpecial()
|
||||||
&& Config.Client.Advanced.Graphics.Fog.disableVanillaFog.get())
|
&& 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.fogStart(A_REALLY_REALLY_BIG_VALUE);
|
||||||
RenderSystem.fogEnd(A_EVEN_LARGER_VALUE);
|
RenderSystem.fogEnd(A_EVEN_LARGER_VALUE);
|
||||||
#else
|
#else
|
||||||
|
|||||||
+1
-1
@@ -16,7 +16,7 @@ public class MixinGameRenderer
|
|||||||
private static final Logger LOGGER = LogManager.getLogger(MixinGameRenderer.class.getSimpleName());
|
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...
|
// FIXME: This I think will dup multiple renderStartupEvent calls...
|
||||||
@Inject(method = {"reloadShaders", "preloadUiShader"}, at = @At("TAIL"))
|
@Inject(method = {"reloadShaders", "preloadUiShader"}, at = @At("TAIL"))
|
||||||
public void onStartupShaders(CallbackInfo ci)
|
public void onStartupShaders(CallbackInfo ci)
|
||||||
|
|||||||
+58
-37
@@ -20,26 +20,27 @@
|
|||||||
package com.seibel.distanthorizons.fabric.mixins.client;
|
package com.seibel.distanthorizons.fabric.mixins.client;
|
||||||
|
|
||||||
import com.mojang.blaze3d.vertex.PoseStack;
|
import com.mojang.blaze3d.vertex.PoseStack;
|
||||||
#if PRE_MC_1_19_4
|
#if MC_VER < MC_1_19_4
|
||||||
import com.mojang.math.Matrix4f;
|
import com.mojang.math.Matrix4f;
|
||||||
|
import org.lwjgl.opengl.GL32;
|
||||||
#else
|
#else
|
||||||
import net.minecraft.client.Camera;
|
|
||||||
import net.minecraft.client.renderer.GameRenderer;
|
|
||||||
import net.minecraft.client.renderer.LightTexture;
|
|
||||||
import org.joml.Matrix4f;
|
import org.joml.Matrix4f;
|
||||||
#endif
|
#endif
|
||||||
import com.seibel.distanthorizons.common.wrappers.chunk.ChunkWrapper;
|
import com.seibel.distanthorizons.common.wrappers.chunk.ChunkWrapper;
|
||||||
import com.seibel.distanthorizons.core.config.Config;
|
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.core.util.math.Mat4f;
|
||||||
import net.minecraft.client.Camera;
|
import net.minecraft.client.Camera;
|
||||||
import net.minecraft.client.multiplayer.ClientLevel;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.renderer.GameRenderer;
|
import net.minecraft.client.renderer.GameRenderer;
|
||||||
import net.minecraft.client.renderer.LevelRenderer;
|
|
||||||
import net.minecraft.client.renderer.LightTexture;
|
import net.minecraft.client.renderer.LightTexture;
|
||||||
|
import com.seibel.distanthorizons.core.config.Config;
|
||||||
|
import net.minecraft.client.multiplayer.ClientLevel;
|
||||||
|
import net.minecraft.client.renderer.LevelRenderer;
|
||||||
import net.minecraft.client.renderer.RenderType;
|
import net.minecraft.client.renderer.RenderType;
|
||||||
import net.minecraft.world.level.lighting.LevelLightEngine;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
import org.spongepowered.asm.mixin.Unique;
|
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
@@ -62,50 +63,67 @@ public class MixinLevelRenderer
|
|||||||
{
|
{
|
||||||
@Shadow
|
@Shadow
|
||||||
private ClientLevel level;
|
private ClientLevel level;
|
||||||
@Unique
|
|
||||||
private static float previousPartialTicks = 0;
|
|
||||||
|
|
||||||
// Inject rendering at first call to renderChunkLayer
|
#if MC_VER < MC_1_17_1
|
||||||
// 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
|
|
||||||
@Inject(at = @At("HEAD"),
|
@Inject(at = @At("HEAD"),
|
||||||
method = "renderChunkLayer(Lnet/minecraft/client/renderer/RenderType;Lcom/mojang/blaze3d/vertex/PoseStack;DDD)V",
|
method = "renderChunkLayer(Lnet/minecraft/client/renderer/RenderType;Lcom/mojang/blaze3d/vertex/PoseStack;DDD)V",
|
||||||
cancellable = true)
|
cancellable = true)
|
||||||
private void renderChunkLayer(RenderType renderType, PoseStack matrixStackIn, double xIn, double yIn, double zIn, CallbackInfo callback)
|
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"),
|
@Inject(at = @At("HEAD"),
|
||||||
method = "renderChunkLayer(Lnet/minecraft/client/renderer/RenderType;Lcom/mojang/blaze3d/vertex/PoseStack;DDDLcom/mojang/math/Matrix4f;)V",
|
method = "renderChunkLayer(Lnet/minecraft/client/renderer/RenderType;Lcom/mojang/blaze3d/vertex/PoseStack;DDDLcom/mojang/math/Matrix4f;)V",
|
||||||
cancellable = true)
|
cancellable = true)
|
||||||
private void renderChunkLayer(RenderType renderType, PoseStack modelViewMatrixStack, double cameraXBlockPos, double cameraYBlockPos, double cameraZBlockPos, Matrix4f projectionMatrix, CallbackInfo callback)
|
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"),
|
@Inject(at = @At("HEAD"),
|
||||||
method = "renderChunkLayer(Lnet/minecraft/client/renderer/RenderType;Lcom/mojang/blaze3d/vertex/PoseStack;DDDLorg/joml/Matrix4f;)V",
|
method = "renderChunkLayer(Lnet/minecraft/client/renderer/RenderType;Lcom/mojang/blaze3d/vertex/PoseStack;DDDLorg/joml/Matrix4f;)V",
|
||||||
cancellable = true)
|
cancellable = true)
|
||||||
private void renderChunkLayer(RenderType renderType, PoseStack modelViewMatrixStack, double cameraXBlockPos, double cameraYBlockPos, double cameraZBlockPos, Matrix4f projectionMatrix, CallbackInfo callback)
|
private void renderChunkLayer(RenderType renderType, PoseStack modelViewMatrixStack, double cameraXBlockPos, double cameraYBlockPos, double cameraZBlockPos, Matrix4f projectionMatrix, CallbackInfo callback)
|
||||||
#else
|
#elif MC_VER < MC_1_20_6
|
||||||
@Inject(at = @At("HEAD"),
|
@Inject(at = @At("HEAD"),
|
||||||
method = "Lnet/minecraft/client/renderer/LevelRenderer;renderSectionLayer(Lnet/minecraft/client/renderer/RenderType;Lcom/mojang/blaze3d/vertex/PoseStack;DDDLorg/joml/Matrix4f;)V",
|
method = "Lnet/minecraft/client/renderer/LevelRenderer;renderSectionLayer(Lnet/minecraft/client/renderer/RenderType;Lcom/mojang/blaze3d/vertex/PoseStack;DDDLorg/joml/Matrix4f;)V",
|
||||||
cancellable = true)
|
cancellable = true)
|
||||||
private void renderChunkLayer(RenderType renderType, PoseStack modelViewMatrixStack, double camX, double camY, double camZ, Matrix4f projectionMatrix, CallbackInfo callback)
|
private void renderChunkLayer(RenderType renderType, PoseStack modelViewMatrixStack, double camX, double camY, double camZ, Matrix4f projectionMatrix, CallbackInfo callback)
|
||||||
|
#else
|
||||||
|
@Inject(at = @At("HEAD"),
|
||||||
|
method = "Lnet/minecraft/client/renderer/LevelRenderer;renderSectionLayer(Lnet/minecraft/client/renderer/RenderType;DDDLorg/joml/Matrix4f;Lorg/joml/Matrix4f;)V",
|
||||||
|
cancellable = true)
|
||||||
|
private void renderChunkLayer(RenderType renderType, double x, double y, double z, Matrix4f projectionMatrix, Matrix4f frustumMatrix, CallbackInfo callback)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
|
#if MC_VER == MC_1_16_5
|
||||||
|
// get the matrices from the OpenGL fixed pipeline
|
||||||
|
float[] mcProjMatrixRaw = new float[16];
|
||||||
|
GL32.glGetFloatv(GL32.GL_PROJECTION_MATRIX, mcProjMatrixRaw);
|
||||||
|
Mat4f mcProjectionMatrix = new Mat4f(mcProjMatrixRaw);
|
||||||
|
mcProjectionMatrix.transpose();
|
||||||
|
|
||||||
|
Mat4f mcModelViewMatrix = McObjectConverter.Convert(matrixStackIn.last().pose());
|
||||||
|
|
||||||
|
#elif MC_VER <= MC_1_20_4
|
||||||
|
// get the matrices directly from MC
|
||||||
|
Mat4f mcModelViewMatrix = McObjectConverter.Convert(modelViewMatrixStack.last().pose());
|
||||||
|
Mat4f mcProjectionMatrix = McObjectConverter.Convert(projectionMatrix);
|
||||||
|
#else
|
||||||
|
// MC combined the model view and projection matricies
|
||||||
|
Mat4f mcModelViewMatrix = McObjectConverter.Convert(projectionMatrix);
|
||||||
|
Mat4f mcProjectionMatrix = new Mat4f();
|
||||||
|
mcProjectionMatrix.setIdentity();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (renderType.equals(RenderType.translucent()))
|
||||||
|
{
|
||||||
|
ClientApi.INSTANCE.renderDeferredLods(ClientLevelWrapper.getWrapper(this.level),
|
||||||
|
mcModelViewMatrix,
|
||||||
|
mcProjectionMatrix,
|
||||||
|
#if MC_VER < MC_1_21
|
||||||
|
Minecraft.getInstance().getFrameTime()
|
||||||
|
#else
|
||||||
|
Minecraft.getInstance().getTimer().getRealtimeDeltaTicks()
|
||||||
|
#endif
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// FIXME completely disables rendering when sodium is installed
|
// FIXME completely disables rendering when sodium is installed
|
||||||
if (Config.Client.Advanced.Debugging.lodOnlyMode.get())
|
if (Config.Client.Advanced.Debugging.lodOnlyMode.get())
|
||||||
{
|
{
|
||||||
@@ -113,15 +131,18 @@ 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")
|
@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)
|
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")
|
@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)
|
public void callAfterRunUpdates(PoseStack poseStack, float partialTick, long finishNanoTime, boolean renderBlockOutline, Camera camera, GameRenderer gameRenderer, LightTexture lightTexture, Matrix4f projectionMatrix, CallbackInfo ci)
|
||||||
#else
|
#elif MC_VER < MC_1_20_6
|
||||||
@Inject(at = @At(value = "TAIL", target = "Lnet/minecraft/world/level/lighting/LevelLightEngine;runLightUpdates()I"), method = "renderLevel")
|
@Inject(at = @At(value = "TAIL", target = "Lnet/minecraft/world/level/lighting/LevelLightEngine;runLightUpdates()I"), method = "renderLevel")
|
||||||
private void callAfterRunUpdates(PoseStack poseStack, float partialTick, long finishNanoTime, boolean renderBlockOutline, Camera camera, GameRenderer gameRenderer, LightTexture lightTexture, Matrix4f projectionMatrix, CallbackInfo ci)
|
private void callAfterRunUpdates(PoseStack poseStack, float partialTick, long finishNanoTime, boolean renderBlockOutline, Camera camera, GameRenderer gameRenderer, LightTexture lightTexture, Matrix4f projectionMatrix, CallbackInfo ci)
|
||||||
|
#else
|
||||||
|
@Inject(at = @At(value = "TAIL", target = "Lnet/minecraft/world/level/lighting/LevelLightEngine;runLightUpdates()I"), method = "renderLevel")
|
||||||
|
private void callAfterRunUpdates(CallbackInfo ci)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
ChunkWrapper.syncedUpdateClientLightStatus();
|
ChunkWrapper.syncedUpdateClientLightStatus();
|
||||||
|
|||||||
+19
-7
@@ -20,9 +20,14 @@
|
|||||||
package com.seibel.distanthorizons.fabric.mixins.client;
|
package com.seibel.distanthorizons.fabric.mixins.client;
|
||||||
|
|
||||||
|
|
||||||
import com.seibel.distanthorizons.common.util.ILightTextureMarker;
|
import com.mojang.blaze3d.platform.NativeImage;
|
||||||
|
|
||||||
|
import com.seibel.distanthorizons.common.wrappers.minecraft.MinecraftRenderWrapper;
|
||||||
|
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||||
|
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
|
||||||
|
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
|
||||||
import net.minecraft.client.renderer.LightTexture;
|
import net.minecraft.client.renderer.LightTexture;
|
||||||
import net.minecraft.client.renderer.texture.DynamicTexture;
|
|
||||||
import org.spongepowered.asm.mixin.Final;
|
import org.spongepowered.asm.mixin.Final;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
@@ -35,13 +40,20 @@ public class MixinLightTexture
|
|||||||
{
|
{
|
||||||
@Shadow
|
@Shadow
|
||||||
@Final
|
@Final
|
||||||
private DynamicTexture lightTexture;
|
private NativeImage lightPixels;
|
||||||
|
|
||||||
@Inject(method = "<init>", at = @At("RETURN"))
|
|
||||||
public void markLightTexture(CallbackInfo ci)
|
@Inject(method = "updateLightTexture(F)V", at = @At("RETURN"))
|
||||||
|
public void updateLightTexture(float partialTicks, CallbackInfo ci)
|
||||||
{
|
{
|
||||||
//
|
IMinecraftClientWrapper mc = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class);
|
||||||
((ILightTextureMarker) this.lightTexture).markLightTexture();
|
if (mc == null || mc.getWrappedClientLevel() == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
IClientLevelWrapper clientLevel = mc.getWrappedClientLevel();
|
||||||
|
MinecraftRenderWrapper.INSTANCE.updateLightmap(this.lightPixels, clientLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+38
-11
@@ -1,6 +1,6 @@
|
|||||||
package com.seibel.distanthorizons.fabric.mixins.client;
|
package com.seibel.distanthorizons.fabric.mixins.client;
|
||||||
|
|
||||||
import com.seibel.distanthorizons.api.enums.config.EUpdateBranch;
|
import com.seibel.distanthorizons.api.enums.config.EDhApiUpdateBranch;
|
||||||
import com.seibel.distanthorizons.common.wrappers.gui.updater.UpdateModScreen;
|
import com.seibel.distanthorizons.common.wrappers.gui.updater.UpdateModScreen;
|
||||||
import com.seibel.distanthorizons.core.config.Config;
|
import com.seibel.distanthorizons.core.config.Config;
|
||||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||||
@@ -8,10 +8,12 @@ import com.seibel.distanthorizons.core.jar.installer.GitlabGetter;
|
|||||||
import com.seibel.distanthorizons.core.jar.installer.ModrinthGetter;
|
import com.seibel.distanthorizons.core.jar.installer.ModrinthGetter;
|
||||||
import com.seibel.distanthorizons.core.jar.updater.SelfUpdater;
|
import com.seibel.distanthorizons.core.jar.updater.SelfUpdater;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.IVersionConstants;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.IVersionConstants;
|
||||||
import net.minecraft.client.Minecraft;
|
import com.seibel.distanthorizons.coreapi.ModInfo;
|
||||||
import net.minecraft.client.gui.screens.Screen;
|
import net.minecraft.client.gui.screens.Screen;
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.gui.screens.TitleScreen;
|
import net.minecraft.client.gui.screens.TitleScreen;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Unique;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||||
@@ -25,8 +27,17 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
|||||||
@Mixin(Minecraft.class)
|
@Mixin(Minecraft.class)
|
||||||
public class MixinMinecraft
|
public class MixinMinecraft
|
||||||
{
|
{
|
||||||
#if PRE_MC_1_20_2
|
/**
|
||||||
#if MC_1_20_1
|
* Can be enabled for testing the auto updater UI. <br/>
|
||||||
|
* will always show the auto updater if set to true.
|
||||||
|
*/
|
||||||
|
@Unique
|
||||||
|
private static final boolean DEBUG_ALWAYS_SHOW_UPDATER = false;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#if MC_VER < MC_1_20_2
|
||||||
|
#if MC_VER == MC_1_20_1
|
||||||
@Redirect(
|
@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",
|
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")
|
at = @At(value = "INVOKE", target = "Lnet/minecraft/client/Minecraft;setScreen(Lnet/minecraft/client/gui/screens/Screen;)V")
|
||||||
@@ -41,17 +52,17 @@ public class MixinMinecraft
|
|||||||
public void onOpenScreen(Minecraft instance, Screen guiScreen)
|
public void onOpenScreen(Minecraft instance, Screen guiScreen)
|
||||||
{
|
{
|
||||||
#endif
|
#endif
|
||||||
if (!Config.Client.Advanced.AutoUpdater.enableAutoUpdater.get()) // Don't do anything if the user doesn't want it
|
if (!Config.Client.Advanced.AutoUpdater.enableAutoUpdater.get() && !DEBUG_ALWAYS_SHOW_UPDATER) // Don't do anything if the user doesn't want it
|
||||||
{
|
{
|
||||||
instance.setScreen(guiScreen); // Sets the screen back to the vanilla screen as if nothing ever happened
|
instance.setScreen(guiScreen); // Sets the screen back to the vanilla screen as if nothing ever happened
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SelfUpdater.onStart())
|
if (SelfUpdater.onStart() || DEBUG_ALWAYS_SHOW_UPDATER)
|
||||||
{
|
{
|
||||||
instance.setScreen(new UpdateModScreen(
|
instance.setScreen(new UpdateModScreen(
|
||||||
new TitleScreen(false), // We don't want to use the vanilla title screen as it would fade the buttons
|
new TitleScreen(false), // We don't want to use the vanilla title screen as it would fade the buttons
|
||||||
(Config.Client.Advanced.AutoUpdater.updateBranch.get() == EUpdateBranch.STABLE ? ModrinthGetter.getLatestIDForVersion(SingletonInjector.INSTANCE.get(IVersionConstants.class).getMinecraftVersion()): GitlabGetter.INSTANCE.projectPipelines.get(0).get("sha"))
|
(Config.Client.Advanced.AutoUpdater.updateBranch.get() == EDhApiUpdateBranch.STABLE ? ModrinthGetter.getLatestIDForVersion(SingletonInjector.INSTANCE.get(IVersionConstants.class).getMinecraftVersion()): GitlabGetter.INSTANCE.projectPipelines.get(0).get("sha"))
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -61,7 +72,7 @@ public class MixinMinecraft
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if POST_MC_1_20_2
|
#if MC_VER >= MC_1_20_2
|
||||||
@Redirect(
|
@Redirect(
|
||||||
method = "Lnet/minecraft/client/Minecraft;onGameLoadFinished(Lnet/minecraft/client/Minecraft$GameLoadCookie;)V",
|
method = "Lnet/minecraft/client/Minecraft;onGameLoadFinished(Lnet/minecraft/client/Minecraft$GameLoadCookie;)V",
|
||||||
at = @At(value = "INVOKE", target = "Ljava/lang/Runnable;run()V")
|
at = @At(value = "INVOKE", target = "Ljava/lang/Runnable;run()V")
|
||||||
@@ -69,15 +80,31 @@ public class MixinMinecraft
|
|||||||
private void buildInitialScreens(Runnable runnable)
|
private void buildInitialScreens(Runnable runnable)
|
||||||
{
|
{
|
||||||
if (
|
if (
|
||||||
Config.Client.Advanced.AutoUpdater.enableAutoUpdater.get() // Don't do anything if the user doesn't want it
|
DEBUG_ALWAYS_SHOW_UPDATER ||
|
||||||
|
(
|
||||||
|
// Don't do anything if the user doesn't want it
|
||||||
|
Config.Client.Advanced.AutoUpdater.enableAutoUpdater.get()
|
||||||
&& SelfUpdater.onStart()
|
&& SelfUpdater.onStart()
|
||||||
)
|
)
|
||||||
|
)
|
||||||
{
|
{
|
||||||
runnable = () -> {
|
runnable = () ->
|
||||||
|
{
|
||||||
|
String versionId;
|
||||||
|
EDhApiUpdateBranch updateBranch = EDhApiUpdateBranch.convertAutoToStableOrNightly(Config.Client.Advanced.AutoUpdater.updateBranch.get());
|
||||||
|
if (updateBranch == EDhApiUpdateBranch.STABLE)
|
||||||
|
{
|
||||||
|
versionId = ModrinthGetter.getLatestIDForVersion(SingletonInjector.INSTANCE.get(IVersionConstants.class).getMinecraftVersion());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
versionId = GitlabGetter.INSTANCE.projectPipelines.getFirst().get("sha");
|
||||||
|
}
|
||||||
|
|
||||||
Minecraft.getInstance().setScreen(new UpdateModScreen(
|
Minecraft.getInstance().setScreen(new UpdateModScreen(
|
||||||
// TODO: Change to runnable, instead of tittle screen
|
// TODO: Change to runnable, instead of tittle screen
|
||||||
new TitleScreen(false), // We don't want to use the vanilla title screen as it would fade the buttons
|
new TitleScreen(false), // We don't want to use the vanilla title screen as it would fade the buttons
|
||||||
(Config.Client.Advanced.AutoUpdater.updateBranch.get() == EUpdateBranch.STABLE ? ModrinthGetter.getLatestIDForVersion(SingletonInjector.INSTANCE.get(IVersionConstants.class).getMinecraftVersion()) : GitlabGetter.INSTANCE.projectPipelines.get(0).get("sha"))
|
versionId
|
||||||
));
|
));
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
+93
-18
@@ -23,59 +23,134 @@ import com.seibel.distanthorizons.common.wrappers.gui.GetConfigScreen;
|
|||||||
import com.seibel.distanthorizons.common.wrappers.gui.TexturedButtonWidget;
|
import com.seibel.distanthorizons.common.wrappers.gui.TexturedButtonWidget;
|
||||||
import com.seibel.distanthorizons.coreapi.ModInfo;
|
import com.seibel.distanthorizons.coreapi.ModInfo;
|
||||||
import com.seibel.distanthorizons.core.config.Config;
|
import com.seibel.distanthorizons.core.config.Config;
|
||||||
import net.minecraft.client.gui.screens.OptionsScreen;
|
|
||||||
import net.minecraft.client.gui.screens.Screen;
|
import net.minecraft.client.gui.screens.Screen;
|
||||||
import net.minecraft.network.chat.Component;
|
import net.minecraft.network.chat.Component;
|
||||||
#if PRE_MC_1_19_2
|
#if MC_VER < MC_1_19_2
|
||||||
import net.minecraft.network.chat.TranslatableComponent;
|
import net.minecraft.network.chat.TranslatableComponent;
|
||||||
#endif
|
#endif
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Unique;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
|
#if MC_VER >= MC_1_20_6
|
||||||
|
import net.minecraft.client.gui.layouts.LinearLayout;
|
||||||
|
import net.minecraft.client.gui.layouts.HeaderAndFooterLayout;
|
||||||
|
import org.spongepowered.asm.mixin.Final;
|
||||||
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if MC_VER < MC_1_21
|
||||||
|
import net.minecraft.client.gui.screens.OptionsScreen;
|
||||||
|
#else
|
||||||
|
import net.minecraft.client.gui.screens.options.OptionsScreen;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a button to the menu to goto the config
|
* Adds a button to the menu to goto the config
|
||||||
*
|
*
|
||||||
* @author coolGi
|
* @author coolGi
|
||||||
* @version 12-02-2021
|
* @version 2024-5-20
|
||||||
*/
|
*/
|
||||||
@Mixin(OptionsScreen.class)
|
@Mixin(OptionsScreen.class)
|
||||||
public class MixinOptionsScreen extends Screen
|
public class MixinOptionsScreen extends Screen
|
||||||
{
|
{
|
||||||
// Get the texture for the button
|
/** Texture used for the config opening button */
|
||||||
private static final ResourceLocation ICON_TEXTURE = new ResourceLocation(ModInfo.ID, "textures/gui/button.png");
|
@Unique
|
||||||
protected MixinOptionsScreen(Component title)
|
private static final ResourceLocation ICON_TEXTURE =
|
||||||
{
|
#if MC_VER < MC_1_21
|
||||||
super(title);
|
new ResourceLocation(ModInfo.ID, "textures/gui/button.png");
|
||||||
}
|
#else
|
||||||
|
ResourceLocation.fromNamespaceAndPath(ModInfo.ID, "textures/gui/button.png");
|
||||||
|
#endif
|
||||||
|
|
||||||
@Inject(at = @At("HEAD"), method = "init")
|
|
||||||
|
@Unique
|
||||||
|
private TexturedButtonWidget optionsButton = null;
|
||||||
|
|
||||||
|
#if MC_VER >= MC_1_20_6
|
||||||
|
@Shadow
|
||||||
|
@Final
|
||||||
|
protected HeaderAndFooterLayout layout;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//==============//
|
||||||
|
// constructors //
|
||||||
|
//==============//
|
||||||
|
|
||||||
|
protected MixinOptionsScreen(Component title) { super(title); }
|
||||||
|
|
||||||
|
@Inject(at = @At("RETURN"), method = "init")
|
||||||
private void lodconfig$init(CallbackInfo ci)
|
private void lodconfig$init(CallbackInfo ci)
|
||||||
{
|
{
|
||||||
if (Config.Client.optionsButton.get())
|
if (Config.Client.optionsButton.get())
|
||||||
this. #if PRE_MC_1_17_1 addButton #else addRenderableWidget #endif
|
{
|
||||||
(new TexturedButtonWidget(
|
#if MC_VER < MC_1_17_1
|
||||||
|
this.addButton(this.getOptionsButton());
|
||||||
|
#elif MC_VER < MC_1_20_6
|
||||||
|
this.addRenderableWidget(this.getOptionsButton());
|
||||||
|
#else
|
||||||
|
|
||||||
|
// add the button so it's rendered
|
||||||
|
this.addRenderableWidget(this.getOptionsButton());
|
||||||
|
|
||||||
|
// add the button to the correct location in the UI
|
||||||
|
// TODO is there a better way to do this instead of using access transformers to inject into the exact UI elements?
|
||||||
|
LinearLayout layout = (LinearLayout) this.layout.headerFrame.children.getFirst().child;
|
||||||
|
|
||||||
|
// determine how wide the other option buttons are so we can put our botton to the left of them all
|
||||||
|
AtomicInteger width = new AtomicInteger(0);
|
||||||
|
layout.visitChildren(x -> width.addAndGet(x.getWidth()));
|
||||||
|
width.addAndGet(-10); // padding between the DH button and the FOV slider
|
||||||
|
|
||||||
|
layout.wrapped.addChild(this.getOptionsButton(), 1, 2, (settings) -> settings.paddingLeft(width.get() * -1));
|
||||||
|
layout.arrangeElements();
|
||||||
|
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//================//
|
||||||
|
// helper methods //
|
||||||
|
//================//
|
||||||
|
|
||||||
|
@Unique
|
||||||
|
public TexturedButtonWidget getOptionsButton()
|
||||||
|
{
|
||||||
|
if (this.optionsButton == null)
|
||||||
|
{
|
||||||
|
this.optionsButton
|
||||||
|
= new TexturedButtonWidget(
|
||||||
// Where the button is on the screen
|
// Where the button is on the screen
|
||||||
this.width / 2 - 180, this.height / 6 - 12,
|
this.width / 2 - 180, this.height / 6 - 12,
|
||||||
// Width and height of the button
|
// Width and height of the button
|
||||||
20, 20,
|
20, 20,
|
||||||
// Offset
|
// texture UV Offset
|
||||||
0, 0,
|
0, 0,
|
||||||
// Some textuary stuff
|
// Some textuary stuff
|
||||||
20, ICON_TEXTURE, 20, 40,
|
20, ICON_TEXTURE, 20, 40,
|
||||||
// Create the button and tell it where to go
|
// Create the button and tell it where to go
|
||||||
// For now it goes to the client option by default
|
// For now it goes to the client option by default
|
||||||
(buttonWidget) -> Objects.requireNonNull(minecraft).setScreen(GetConfigScreen.getScreen(this)),
|
(buttonWidget) -> Objects.requireNonNull(this.minecraft).setScreen(GetConfigScreen.getScreen(this)),
|
||||||
// Add a title to the utton
|
// Add a title to the button
|
||||||
#if PRE_MC_1_19_2
|
#if MC_VER < MC_1_19_2
|
||||||
new TranslatableComponent(ModInfo.ID + ".title")));
|
new TranslatableComponent(ModInfo.ID + ".title"));
|
||||||
#else
|
#else
|
||||||
Component.translatable(ModInfo.ID + ".title")));
|
Component.translatable(ModInfo.ID + ".title"));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return this.optionsButton;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -16,7 +16,7 @@ import org.spongepowered.asm.mixin.injection.Redirect;
|
|||||||
public class MixinTextureUtil
|
public class MixinTextureUtil
|
||||||
{
|
{
|
||||||
@Redirect(method = "Lcom/mojang/blaze3d/platform/TextureUtil;prepareImage(Lcom/mojang/blaze3d/platform/NativeImage$InternalGlFormat;IIII)V",
|
@Redirect(method = "Lcom/mojang/blaze3d/platform/TextureUtil;prepareImage(Lcom/mojang/blaze3d/platform/NativeImage$InternalGlFormat;IIII)V",
|
||||||
at = @At(value = "INVOKE", target = "Lcom/mojang/blaze3d/platform/GlStateManager;_texParameter(IIF)V", #if MC_1_16_5 remap = true #else remap = false #endif))
|
at = @At(value = "INVOKE", target = "Lcom/mojang/blaze3d/platform/GlStateManager;_texParameter(IIF)V", #if MC_VER == MC_1_16_5 remap = true #else remap = false #endif))
|
||||||
private static void setLodBias(int target, int pname, float param)
|
private static void setLodBias(int target, int pname, float param)
|
||||||
{
|
{
|
||||||
float biasValue = Config.Client.Advanced.Graphics.AdvancedGraphics.lodBias.get().floatValue();
|
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
|
@Deprecated // TODO: Not sure if this is needed anymore
|
||||||
public class MixinServerLevel
|
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))
|
// @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) {
|
// private void saveWorldEvent(ProgressListener progressListener, boolean bl, boolean bl2, CallbackInfo ci) {
|
||||||
// Main.client_proxy.worldSaveEvent();
|
// 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
|
/* 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
|
// Sodium 0.5
|
||||||
import com.mojang.blaze3d.vertex.PoseStack;
|
import com.mojang.blaze3d.vertex.PoseStack;
|
||||||
import com.seibel.distanthorizons.core.api.internal.ClientApi;
|
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
|
// Sodium 0.3 to 0.4
|
||||||
import com.seibel.distanthorizons.core.api.internal.ClientApi;
|
import com.seibel.distanthorizons.core.api.internal.ClientApi;
|
||||||
import com.seibel.distanthorizons.core.dependencyInjection.ModAccessorInjector;
|
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 org.spongepowered.asm.mixin.Mixin;
|
||||||
import net.minecraft.world.level.chunk.ChunkGenerator;
|
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.At;
|
||||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||||
|
|
||||||
|
|||||||
+13
-3
@@ -28,16 +28,25 @@ public class MixinChunkMap
|
|||||||
@Final
|
@Final
|
||||||
ServerLevel level;
|
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)
|
private void onChunkSave(ChunkAccess chunk, CallbackInfoReturnable<Boolean> ci)
|
||||||
{
|
{
|
||||||
|
// true means a chunk was saved to disk
|
||||||
|
if (ci.getReturnValue())
|
||||||
|
{
|
||||||
|
// 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 //
|
// corrupt/incomplete chunk validation //
|
||||||
//=====================================//
|
//=====================================//
|
||||||
|
|
||||||
// MC has a tendency to try saving incomplete or corrupted chunks (which show up as empty or black chunks)
|
// 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
|
// this logic should prevent that from happening
|
||||||
#if MC_1_16_5 || MC_1_17_1
|
#if MC_VER == MC_1_16_5 || MC_VER == MC_1_17_1
|
||||||
if (chunk.isUnsaved() || chunk.getUpgradeData() != null || !chunk.isLightCorrect())
|
if (chunk.isUnsaved() || chunk.getUpgradeData() != null || !chunk.isLightCorrect())
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
@@ -55,7 +64,7 @@ public class MixinChunkMap
|
|||||||
//==================//
|
//==================//
|
||||||
|
|
||||||
// some chunks may be missing their biomes, which cause issues when attempting to save them
|
// 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 MC_VER == MC_1_16_5 || MC_VER == MC_1_17_1
|
||||||
if (chunk.getBiomes() == null)
|
if (chunk.getBiomes() == null)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
@@ -79,5 +88,6 @@ public class MixinChunkMap
|
|||||||
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;",
|
@Inject(method = "wrapThreadWithTaskName(Ljava/lang/String;Ljava/lang/Runnable;)Ljava/lang/Runnable;",
|
||||||
at = @At("HEAD"), cancellable = true)
|
at = @At("HEAD"), cancellable = true)
|
||||||
private static void overrideUtil$wrapThreadWithTaskName(String string, Runnable r, CallbackInfoReturnable<Runnable> ci)
|
private static void overrideUtil$wrapThreadWithTaskName(String string, Runnable r, CallbackInfoReturnable<Runnable> ci)
|
||||||
@@ -62,7 +62,7 @@ public class MixinUtilBackgroundThread
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#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;",
|
@Inject(method = "wrapThreadWithTaskName(Ljava/lang/String;Ljava/util/function/Supplier;)Ljava/util/function/Supplier;",
|
||||||
at = @At("HEAD"), cancellable = true)
|
at = @At("HEAD"), cancellable = true)
|
||||||
private static void overrideUtil$wrapThreadWithTaskNameForSupplier(String string, Supplier<?> r, CallbackInfoReturnable<Supplier<?>> ci)
|
private static void overrideUtil$wrapThreadWithTaskNameForSupplier(String string, Supplier<?> r, CallbackInfoReturnable<Supplier<?>> ci)
|
||||||
|
|||||||
-60
@@ -1,60 +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.fabric.mixins.server.unsafe;
|
|
||||||
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
|
|
||||||
//FIXME: Is this still needed?
|
|
||||||
#if POST_MC_1_18_2
|
|
||||||
|
|
||||||
import net.minecraft.util.ThreadingDetector;
|
|
||||||
import org.spongepowered.asm.mixin.Mutable;
|
|
||||||
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;
|
|
||||||
|
|
||||||
import java.util.concurrent.Semaphore;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Why does this exist? But okay! (Will be probably removed when the experimental generator is done)
|
|
||||||
* FIXME: Recheck this
|
|
||||||
*/
|
|
||||||
@Mixin(ThreadingDetector.class)
|
|
||||||
public class MixinThreadingDetector
|
|
||||||
{
|
|
||||||
@Mutable
|
|
||||||
@Shadow
|
|
||||||
private Semaphore lock;
|
|
||||||
|
|
||||||
@Inject(method = "<init>", at = @At("RETURN"))
|
|
||||||
private void setSemaphore(CallbackInfo ci)
|
|
||||||
{
|
|
||||||
this.lock = new Semaphore(2);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
|
|
||||||
import net.minecraft.server.level.ServerLevel;
|
|
||||||
|
|
||||||
@Mixin(ServerLevel.class)
|
|
||||||
public class MixinThreadingDetector { } //FIXME: Is there some way to make this file just not be added?
|
|
||||||
#endif
|
|
||||||
+1
-1
@@ -32,7 +32,7 @@ public class ModMenuIntegration implements ModMenuApi
|
|||||||
@Override
|
@Override
|
||||||
public ConfigScreenFactory<?> getModConfigScreenFactory()
|
public ConfigScreenFactory<?> getModConfigScreenFactory()
|
||||||
{
|
{
|
||||||
return parent -> GetConfigScreen.getScreen(parent);
|
return GetConfigScreen::getScreen;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-4
@@ -1,11 +1,11 @@
|
|||||||
package com.seibel.distanthorizons.fabric.wrappers.modAccessor;
|
package com.seibel.distanthorizons.fabric.wrappers.modAccessor;
|
||||||
|
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IBCLibAccessor;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IBCLibAccessor;
|
||||||
#if MC_1_16_5 || MC_1_17_1
|
#if MC_VER == MC_1_16_5 || MC_VER == MC_1_17_1 || MC_VER == MC_1_20_4 || MC_VER == MC_1_20_6 // These versions either don't have BCLib, or the implementation is different
|
||||||
#elif MC_1_18_2
|
#elif MC_VER == MC_1_18_2
|
||||||
import ru.bclib.config.ClientConfig;
|
import ru.bclib.config.ClientConfig;
|
||||||
import ru.bclib.config.Configs;
|
import ru.bclib.config.Configs;
|
||||||
#else
|
#elif MC_VER < MC_1_21
|
||||||
import org.betterx.bclib.config.ClientConfig;
|
import org.betterx.bclib.config.ClientConfig;
|
||||||
import org.betterx.bclib.config.Configs;
|
import org.betterx.bclib.config.Configs;
|
||||||
#endif
|
#endif
|
||||||
@@ -17,7 +17,8 @@ public class BCLibAccessor implements IBCLibAccessor
|
|||||||
|
|
||||||
public void setRenderCustomFog(boolean newValue)
|
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"
|
// only some MC versions have BCLib and require this fix
|
||||||
|
#if (MC_VER > MC_1_17_1 && MC_VER < MC_1_20_4)
|
||||||
|
|
||||||
// Change the value of CUSTOM_FOG_RENDERING in the bclib client config
|
// Change the value of CUSTOM_FOG_RENDERING in the bclib client config
|
||||||
// This disabled fog from rendering within bclib
|
// This disabled fog from rendering within bclib
|
||||||
|
|||||||
+5
-1
@@ -19,10 +19,14 @@
|
|||||||
|
|
||||||
package com.seibel.distanthorizons.fabric.wrappers.modAccessor;
|
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 com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IIrisAccessor;
|
||||||
|
#if MC_VER <= MC_1_20_4
|
||||||
import net.coderbot.iris.Iris;
|
import net.coderbot.iris.Iris;
|
||||||
|
#else
|
||||||
|
import net.irisshaders.iris.Iris;
|
||||||
|
#endif
|
||||||
import net.irisshaders.iris.api.v0.IrisApi;
|
import net.irisshaders.iris.api.v0.IrisApi;
|
||||||
|
|
||||||
public class IrisAccessor implements IIrisAccessor
|
public class IrisAccessor implements IIrisAccessor
|
||||||
|
|||||||
+8
@@ -22,6 +22,8 @@ package com.seibel.distanthorizons.fabric.wrappers.modAccessor;
|
|||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IModChecker;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IModChecker;
|
||||||
import net.fabricmc.loader.api.FabricLoader;
|
import net.fabricmc.loader.api.FabricLoader;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
public class ModChecker implements IModChecker
|
public class ModChecker implements IModChecker
|
||||||
{
|
{
|
||||||
public static final ModChecker INSTANCE = new ModChecker();
|
public static final ModChecker INSTANCE = new ModChecker();
|
||||||
@@ -32,4 +34,10 @@ public class ModChecker implements IModChecker
|
|||||||
return FabricLoader.getInstance().isModLoaded(modid);
|
return FabricLoader.getInstance().isModLoaded(modid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public File modLocation(String modid)
|
||||||
|
{
|
||||||
|
return new File(FabricLoader.getInstance().getModContainer(modid).get().getOrigin().getPaths().getFirst().toUri());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+8
-10
@@ -24,7 +24,7 @@ import java.util.stream.Collectors;
|
|||||||
|
|
||||||
import com.seibel.distanthorizons.core.pos.DhChunkPos;
|
import com.seibel.distanthorizons.core.pos.DhChunkPos;
|
||||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||||
import com.seibel.distanthorizons.coreapi.util.math.Mat4f;
|
import com.seibel.distanthorizons.core.util.math.Mat4f;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.IWrapperFactory;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.IWrapperFactory;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.ISodiumAccessor;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.ISodiumAccessor;
|
||||||
@@ -33,7 +33,7 @@ import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.ISodiumAcce
|
|||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
|
||||||
import me.jellysquid.mods.sodium.client.render.SodiumWorldRenderer;
|
import me.jellysquid.mods.sodium.client.render.SodiumWorldRenderer;
|
||||||
import net.minecraft.client.Minecraft;
|
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.nbt.CompoundTag;
|
||||||
import net.minecraft.network.protocol.Packet;
|
import net.minecraft.network.protocol.Packet;
|
||||||
import net.minecraft.world.entity.Entity;
|
import net.minecraft.world.entity.Entity;
|
||||||
@@ -60,21 +60,19 @@ public class SodiumAccessor implements ISodiumAccessor
|
|||||||
return "Sodium-Fabric";
|
return "Sodium-Fabric";
|
||||||
}
|
}
|
||||||
|
|
||||||
#if POST_MC_1_17_1
|
#if MC_VER >= MC_1_17_1
|
||||||
@Override
|
@Override
|
||||||
public HashSet<DhChunkPos> getNormalRenderedChunks()
|
public HashSet<DhChunkPos> getNormalRenderedChunks()
|
||||||
{
|
{
|
||||||
SodiumWorldRenderer renderer = SodiumWorldRenderer.instance();
|
SodiumWorldRenderer renderer = SodiumWorldRenderer.instance();
|
||||||
LevelHeightAccessor height = Minecraft.getInstance().level;
|
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
|
// TODO: This is just a tmp solution, use a proper solution later
|
||||||
return MC_RENDER.getMaximumRenderedChunks().stream().filter((DhChunkPos chunk) -> {
|
return MC_RENDER.getMaximumRenderedChunks().stream().filter((DhChunkPos chunk) -> (renderer.isBoxVisible(
|
||||||
return (renderer.isBoxVisible(
|
|
||||||
chunk.getMinBlockX() + 1, height.getMinBuildHeight() + 1, chunk.getMinBlockZ() + 1,
|
chunk.getMinBlockX() + 1, height.getMinBuildHeight() + 1, chunk.getMinBlockZ() + 1,
|
||||||
chunk.getMinBlockX() + 15, height.getMaxBuildHeight() - 1, chunk.getMinBlockZ() + 15));
|
chunk.getMinBlockX() + 15, height.getMaxBuildHeight() - 1, chunk.getMinBlockZ() + 15))).collect(Collectors.toCollection(HashSet::new));
|
||||||
}).collect(Collectors.toCollection(HashSet::new));
|
#elif MC_VER >= MC_1_18_2
|
||||||
#elif POST_MC_1_18_2
|
|
||||||
// 0b11 = Lighted chunk & loaded chunk
|
// 0b11 = Lighted chunk & loaded chunk
|
||||||
return renderer.getChunkTracker().getChunks(0b00).filter(
|
return renderer.getChunkTracker().getChunks(0b00).filter(
|
||||||
(long l) -> {
|
(long l) -> {
|
||||||
@@ -134,7 +132,7 @@ public class SodiumAccessor implements ISodiumAccessor
|
|||||||
@Override
|
@Override
|
||||||
public void setFogOcclusion(boolean b)
|
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;
|
me.jellysquid.mods.sodium.client.SodiumClientMod.options().performance.useFogOcclusion = b;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,6 @@
|
|||||||
"minVersion": "0.8",
|
"minVersion": "0.8",
|
||||||
"package": "com.seibel.distanthorizons.fabric.mixins",
|
"package": "com.seibel.distanthorizons.fabric.mixins",
|
||||||
"mixins": [
|
"mixins": [
|
||||||
"server.unsafe.MixinThreadingDetector",
|
|
||||||
"server.MixinChunkGenerator",
|
"server.MixinChunkGenerator",
|
||||||
"server.MixinChunkMap",
|
"server.MixinChunkMap",
|
||||||
"server.MixinUtilBackgroundThread"
|
"server.MixinUtilBackgroundThread"
|
||||||
@@ -15,7 +14,6 @@
|
|||||||
"client.MixinFogRenderer",
|
"client.MixinFogRenderer",
|
||||||
"client.MixinGameRenderer",
|
"client.MixinGameRenderer",
|
||||||
"client.MixinLevelRenderer",
|
"client.MixinLevelRenderer",
|
||||||
"client.MixinDynamicTexture",
|
|
||||||
"client.MixinLightTexture",
|
"client.MixinLightTexture",
|
||||||
"client.MixinOptionsScreen",
|
"client.MixinOptionsScreen",
|
||||||
"client.MixinMinecraft",
|
"client.MixinMinecraft",
|
||||||
|
|||||||
@@ -17,17 +17,17 @@
|
|||||||
},
|
},
|
||||||
|
|
||||||
"license": "LGPL-3",
|
"license": "LGPL-3",
|
||||||
"icon": "icon.png",
|
"icon": "assets/distanthorizons/icon.png",
|
||||||
|
|
||||||
"accessWidener": "distanthorizons.accesswidener",
|
"accessWidener": "distanthorizons.accesswidener",
|
||||||
|
|
||||||
"environment": "*",
|
"environment": "*",
|
||||||
"entrypoints": {
|
"entrypoints": {
|
||||||
"client": [
|
"client": [
|
||||||
"com.seibel.distanthorizons.fabric.FabricClientMain"
|
"com.seibel.distanthorizons.fabric.FabricMain"
|
||||||
],
|
],
|
||||||
"server": [
|
"server": [
|
||||||
"com.seibel.distanthorizons.fabric.FabricDedicatedServerMain"
|
"com.seibel.distanthorizons.fabric.FabricMain"
|
||||||
],
|
],
|
||||||
"modmenu": [
|
"modmenu": [
|
||||||
"com.seibel.distanthorizons.fabric.wrappers.config.ModMenuIntegration"
|
"com.seibel.distanthorizons.fabric.wrappers.config.ModMenuIntegration"
|
||||||
@@ -56,7 +56,6 @@
|
|||||||
},
|
},
|
||||||
|
|
||||||
"suggests": {
|
"suggests": {
|
||||||
"blendium": "*"
|
|
||||||
},
|
},
|
||||||
|
|
||||||
"breaks": $fabric_incompatibility_list,
|
"breaks": $fabric_incompatibility_list,
|
||||||
|
|||||||
+21
-33
@@ -1,8 +1,10 @@
|
|||||||
plugins {
|
plugins {
|
||||||
|
// Note: This is only needed for multi-loader projects
|
||||||
|
// The main architectury loom version is set at the start of the root build.gradle
|
||||||
id "architectury-plugin" version "3.4-SNAPSHOT"
|
id "architectury-plugin" version "3.4-SNAPSHOT"
|
||||||
}
|
}
|
||||||
|
|
||||||
sourceCompatibility = targetCompatibility = JavaVersion.VERSION_17
|
sourceCompatibility = targetCompatibility = JavaVersion.VERSION_21
|
||||||
|
|
||||||
architectury {
|
architectury {
|
||||||
platformSetupLoomIde()
|
platformSetupLoomIde()
|
||||||
@@ -18,6 +20,7 @@ architectury {
|
|||||||
//}
|
//}
|
||||||
|
|
||||||
loom {
|
loom {
|
||||||
|
silentMojangMappingsLicense() // Shut the licencing warning
|
||||||
accessWidenerPath = project(":common").file("src/main/resources/${accessWidenerVersion}.distanthorizons.accesswidener")
|
accessWidenerPath = project(":common").file("src/main/resources/${accessWidenerVersion}.distanthorizons.accesswidener")
|
||||||
|
|
||||||
forge {
|
forge {
|
||||||
@@ -25,7 +28,7 @@ loom {
|
|||||||
extraAccessWideners.add loom.accessWidenerPath.get().asFile.name
|
extraAccessWideners.add loom.accessWidenerPath.get().asFile.name
|
||||||
|
|
||||||
mixinConfigs = [
|
mixinConfigs = [
|
||||||
"DistantHorizons.mixins.json"
|
"DistantHorizons.forge.mixins.json"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -36,7 +39,7 @@ loom {
|
|||||||
setConfigName("Forge Client")
|
setConfigName("Forge Client")
|
||||||
ideConfigGenerated(true)
|
ideConfigGenerated(true)
|
||||||
runDir("../run")
|
runDir("../run")
|
||||||
vmArgs("-XX:-OmitStackTraceInFastThrow", minecraftMemoryJavaArg)
|
// vmArgs("-XX:-OmitStackTraceInFastThrow", minecraftMemoryJavaArg)
|
||||||
}
|
}
|
||||||
server {
|
server {
|
||||||
server()
|
server()
|
||||||
@@ -48,18 +51,17 @@ loom {
|
|||||||
}
|
}
|
||||||
|
|
||||||
remapJar {
|
remapJar {
|
||||||
inputFile = shadowJar.archiveFile
|
inputFile = shadeDowngradedApi.archiveFile
|
||||||
dependsOn shadowJar
|
dependsOn shadeDowngradedApi
|
||||||
classifier null
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def addMod(path, enabled) {
|
def addMod(path, enabled) {
|
||||||
if (enabled == "2")
|
if (enabled == "2")
|
||||||
dependencies { implementation(path) }
|
dependencies { implementation(path) }
|
||||||
else if (enabled == "1")
|
else if (enabled == "1")
|
||||||
dependencies { modCompileOnly(path) }
|
dependencies { modCompileOnly(path) }
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
minecraft "com.mojang:minecraft:${rootProject.minecraft_version}"
|
minecraft "com.mojang:minecraft:${rootProject.minecraft_version}"
|
||||||
mappings loom.layered() {
|
mappings loom.layered() {
|
||||||
@@ -72,24 +74,22 @@ dependencies {
|
|||||||
// Forge
|
// Forge
|
||||||
forge "net.minecraftforge:forge:${rootProject.minecraft_version}-${rootProject.forge_version}"
|
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}")
|
|
||||||
// } else {
|
|
||||||
// implementation("dev.architectury:architectury-forge:${rootProject.architectury_version}")
|
|
||||||
// }
|
|
||||||
|
|
||||||
// Starlight
|
|
||||||
addMod("curse.maven:starlight-forge-526854:${rootProject.starlight_version_forge}", rootProject.enable_starlight_forge)
|
|
||||||
// annotationProcessor "org.spongepowered:mixin:0.8.4:processor"
|
|
||||||
|
|
||||||
addMod("curse.maven:TerraForged-363820:${rootProject.terraforged_version}", rootProject.enable_terraforged)
|
addMod("curse.maven:TerraForged-363820:${rootProject.terraforged_version}", rootProject.enable_terraforged)
|
||||||
|
|
||||||
addMod("curse.maven:TerraFirmaCraft-302973:4616004", rootProject.enable_terrafirmacraft)
|
addMod("curse.maven:TerraFirmaCraft-302973:4616004", rootProject.enable_terrafirmacraft)
|
||||||
|
|
||||||
// if (System.getProperty("idea.sync.active") != "true") {
|
|
||||||
// annotationProcessor "org.spongepowered:mixin:0.8.4:processor"
|
if ( // Only run on MC 1.20.6 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() >= 6
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
// (potential) hack fix, force jopt-simple to be exactly 5.0.4 because Mojang ships that version, but some transitive dependencies request 6.0+
|
||||||
|
implementation('net.sf.jopt-simple:jopt-simple:5.0.4') //{ version { strictly '5.0.4' } }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
task deleteResources(type: Delete) {
|
task deleteResources(type: Delete) {
|
||||||
@@ -110,15 +110,3 @@ tasks.named('runClient') {
|
|||||||
finalizedBy(deleteResources)
|
finalizedBy(deleteResources)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
sourcesJar {
|
|
||||||
def commonSources = project(":common").sourcesJar
|
|
||||||
dependsOn commonSources
|
|
||||||
from commonSources.archiveFile.map { zipTree(it) }
|
|
||||||
}
|
|
||||||
|
|
||||||
//components.java {
|
|
||||||
// withVariantsFromConfiguration(project.configurations.shadowRuntimeElements) {
|
|
||||||
// skip()
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
@@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
package com.seibel.distanthorizons.forge;
|
package com.seibel.distanthorizons.forge;
|
||||||
|
|
||||||
|
import com.seibel.distanthorizons.common.AbstractModInitializer;
|
||||||
import com.seibel.distanthorizons.common.util.ProxyUtil;
|
import com.seibel.distanthorizons.common.util.ProxyUtil;
|
||||||
import com.seibel.distanthorizons.common.wrappers.minecraft.MinecraftRenderWrapper;
|
import com.seibel.distanthorizons.common.wrappers.minecraft.MinecraftRenderWrapper;
|
||||||
import com.seibel.distanthorizons.common.wrappers.world.ClientLevelWrapper;
|
import com.seibel.distanthorizons.common.wrappers.world.ClientLevelWrapper;
|
||||||
@@ -26,6 +27,7 @@ import com.seibel.distanthorizons.core.api.internal.ClientApi;
|
|||||||
import com.seibel.distanthorizons.core.api.internal.SharedApi;
|
import com.seibel.distanthorizons.core.api.internal.SharedApi;
|
||||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||||
|
import com.seibel.distanthorizons.core.util.threading.ThreadPoolUtil;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.chunk.IChunkWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.chunk.IChunkWrapper;
|
||||||
|
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
|
||||||
@@ -36,7 +38,7 @@ import com.seibel.distanthorizons.coreapi.ModInfo;
|
|||||||
import net.minecraft.world.level.LevelAccessor;
|
import net.minecraft.world.level.LevelAccessor;
|
||||||
|
|
||||||
import net.minecraft.client.multiplayer.ClientLevel;
|
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.ChunkEvent;
|
||||||
import net.minecraftforge.event.world.WorldEvent;
|
import net.minecraftforge.event.world.WorldEvent;
|
||||||
#else
|
#else
|
||||||
@@ -44,13 +46,13 @@ import net.minecraftforge.event.level.ChunkEvent;
|
|||||||
import net.minecraftforge.event.level.LevelEvent;
|
import net.minecraftforge.event.level.LevelEvent;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if POST_MC_1_18_2
|
#if MC_VER >= MC_1_18_2
|
||||||
import net.minecraftforge.client.event.RenderLevelStageEvent;
|
import net.minecraftforge.client.event.RenderLevelStageEvent;
|
||||||
#endif
|
#endif
|
||||||
import net.minecraftforge.event.entity.player.PlayerInteractEvent;
|
import net.minecraftforge.event.entity.player.PlayerInteractEvent;
|
||||||
import net.minecraft.world.level.chunk.ChunkAccess;
|
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.NetworkRegistry;
|
||||||
//import net.minecraftforge.network.simple.SimpleChannel;
|
//import net.minecraftforge.network.simple.SimpleChannel;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
@@ -64,6 +66,8 @@ import net.minecraftforge.event.TickEvent;
|
|||||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||||
import org.lwjgl.opengl.GL32;
|
import org.lwjgl.opengl.GL32;
|
||||||
|
|
||||||
|
import java.util.concurrent.ThreadPoolExecutor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This handles all events sent to the client,
|
* This handles all events sent to the client,
|
||||||
* and is the starting point for most of the mod.
|
* and is the starting point for most of the mod.
|
||||||
@@ -71,7 +75,7 @@ import org.lwjgl.opengl.GL32;
|
|||||||
* @author James_Seibel
|
* @author James_Seibel
|
||||||
* @version 2023-7-27
|
* @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 IMinecraftClientWrapper MC = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class);
|
||||||
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
|
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
|
||||||
@@ -79,7 +83,7 @@ public class ForgeClientProxy
|
|||||||
// private static SimpleChannel multiversePluginChannel;
|
// 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(); }
|
private static LevelAccessor GetEventLevel(WorldEvent e) { return e.getWorld(); }
|
||||||
#else
|
#else
|
||||||
private static LevelAccessor GetEventLevel(LevelEvent e) { return e.getLevel(); }
|
private static LevelAccessor GetEventLevel(LevelEvent e) { return e.getLevel(); }
|
||||||
@@ -87,6 +91,15 @@ public class ForgeClientProxy
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void registerEvents()
|
||||||
|
{
|
||||||
|
MinecraftForge.EVENT_BUS.register(this);
|
||||||
|
this.setupNetworkingListeners();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//=============//
|
//=============//
|
||||||
// tick events //
|
// tick events //
|
||||||
//=============//
|
//=============//
|
||||||
@@ -107,7 +120,7 @@ public class ForgeClientProxy
|
|||||||
//==============//
|
//==============//
|
||||||
|
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
#if PRE_MC_1_19_2
|
#if MC_VER < MC_1_19_2
|
||||||
public void clientLevelLoadEvent(WorldEvent.Load event)
|
public void clientLevelLoadEvent(WorldEvent.Load event)
|
||||||
#else
|
#else
|
||||||
public void clientLevelLoadEvent(LevelEvent.Load event)
|
public void clientLevelLoadEvent(LevelEvent.Load event)
|
||||||
@@ -115,7 +128,7 @@ public class ForgeClientProxy
|
|||||||
{
|
{
|
||||||
LOGGER.info("level load");
|
LOGGER.info("level load");
|
||||||
|
|
||||||
#if PRE_MC_1_19_2
|
#if MC_VER < MC_1_19_2
|
||||||
LevelAccessor level = event.getWorld();
|
LevelAccessor level = event.getWorld();
|
||||||
#else
|
#else
|
||||||
LevelAccessor level = event.getLevel();
|
LevelAccessor level = event.getLevel();
|
||||||
@@ -131,15 +144,15 @@ public class ForgeClientProxy
|
|||||||
ClientApi.INSTANCE.clientLevelLoadEvent(clientLevelWrapper);
|
ClientApi.INSTANCE.clientLevelLoadEvent(clientLevelWrapper);
|
||||||
}
|
}
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
#if PRE_MC_1_19_2
|
#if MC_VER < MC_1_19_2
|
||||||
public void clientLevelUnloadEvent(WorldEvent.Unload event)
|
public void clientLevelUnloadEvent(WorldEvent.Unload event)
|
||||||
#else
|
#else
|
||||||
public void clientLevelUnloadEvent(LevelEvent.Load event)
|
public void clientLevelUnloadEvent(LevelEvent.Unload event)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
LOGGER.info("level unload");
|
LOGGER.info("level unload");
|
||||||
|
|
||||||
#if PRE_MC_1_19_2
|
#if MC_VER < MC_1_19_2
|
||||||
LevelAccessor level = event.getWorld();
|
LevelAccessor level = event.getWorld();
|
||||||
#else
|
#else
|
||||||
LevelAccessor level = event.getLevel();
|
LevelAccessor level = event.getLevel();
|
||||||
@@ -163,30 +176,54 @@ public class ForgeClientProxy
|
|||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
public void rightClickBlockEvent(PlayerInteractEvent.RightClickBlock event)
|
public void rightClickBlockEvent(PlayerInteractEvent.RightClickBlock event)
|
||||||
{
|
{
|
||||||
LOGGER.trace("interact or block place event at blockPos: " + event.getPos());
|
if (SharedApi.isChunkAtBlockPosAlreadyUpdating(event.getPos().getX(), event.getPos().getZ()))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
#if PRE_MC_1_19_2
|
//LOGGER.trace("interact or block place event at blockPos: " + event.getPos());
|
||||||
|
|
||||||
|
#if MC_VER < MC_1_19_2
|
||||||
LevelAccessor level = event.getWorld();
|
LevelAccessor level = event.getWorld();
|
||||||
#else
|
#else
|
||||||
LevelAccessor level = event.getLevel();
|
LevelAccessor level = event.getLevel();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
ThreadPoolExecutor executor = ThreadPoolUtil.getFileHandlerExecutor();
|
||||||
|
if (executor != null)
|
||||||
|
{
|
||||||
|
executor.execute(() ->
|
||||||
|
{
|
||||||
ChunkAccess chunk = level.getChunk(event.getPos());
|
ChunkAccess chunk = level.getChunk(event.getPos());
|
||||||
this.onBlockChangeEvent(level, chunk);
|
this.onBlockChangeEvent(level, chunk);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
public void leftClickBlockEvent(PlayerInteractEvent.LeftClickBlock event)
|
public void leftClickBlockEvent(PlayerInteractEvent.LeftClickBlock event)
|
||||||
{
|
{
|
||||||
LOGGER.trace("break or block attack at blockPos: " + event.getPos());
|
if (SharedApi.isChunkAtBlockPosAlreadyUpdating(event.getPos().getX(), event.getPos().getZ()))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
#if PRE_MC_1_19_2
|
//LOGGER.trace("break or block attack at blockPos: " + event.getPos());
|
||||||
|
|
||||||
|
#if MC_VER < MC_1_19_2
|
||||||
LevelAccessor level = event.getWorld();
|
LevelAccessor level = event.getWorld();
|
||||||
#else
|
#else
|
||||||
LevelAccessor level = event.getLevel();
|
LevelAccessor level = event.getLevel();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
ThreadPoolExecutor executor = ThreadPoolUtil.getFileHandlerExecutor();
|
||||||
|
if (executor != null)
|
||||||
|
{
|
||||||
|
executor.execute(() ->
|
||||||
|
{
|
||||||
ChunkAccess chunk = level.getChunk(event.getPos());
|
ChunkAccess chunk = level.getChunk(event.getPos());
|
||||||
this.onBlockChangeEvent(level, chunk);
|
this.onBlockChangeEvent(level, chunk);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
private void onBlockChangeEvent(LevelAccessor level, ChunkAccess chunk)
|
private void onBlockChangeEvent(LevelAccessor level, ChunkAccess chunk)
|
||||||
{
|
{
|
||||||
@@ -217,7 +254,7 @@ public class ForgeClientProxy
|
|||||||
//==============//
|
//==============//
|
||||||
|
|
||||||
@SubscribeEvent
|
@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)
|
if (Minecraft.getInstance().player == null)
|
||||||
{
|
{
|
||||||
@@ -237,8 +274,7 @@ public class ForgeClientProxy
|
|||||||
// networking //
|
// 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 void setupNetworkingListeners()
|
||||||
public static void setupNetworkingListeners(FMLClientSetupEvent event)
|
|
||||||
{
|
{
|
||||||
// multiversePluginChannel = NetworkRegistry.newSimpleChannel(
|
// multiversePluginChannel = NetworkRegistry.newSimpleChannel(
|
||||||
// new ResourceLocation(ModInfo.NETWORKING_RESOURCE_NAMESPACE, ModInfo.MULTIVERSE_PLUGIN_NAMESPACE),
|
// new ResourceLocation(ModInfo.NETWORKING_RESOURCE_NAMESPACE, ModInfo.MULTIVERSE_PLUGIN_NAMESPACE),
|
||||||
@@ -298,20 +334,18 @@ public class ForgeClientProxy
|
|||||||
//===========//
|
//===========//
|
||||||
|
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
#if POST_MC_1_18_2
|
#if MC_VER >= MC_1_18_2
|
||||||
public void afterLevelRenderEvent(RenderLevelStageEvent event)
|
public void afterLevelRenderEvent(RenderLevelStageEvent event)
|
||||||
#else
|
#else
|
||||||
public void afterLevelRenderEvent(TickEvent.RenderTickEvent event)
|
public void afterLevelRenderEvent(TickEvent.RenderTickEvent event)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
#if POST_MC_1_20_1
|
#if MC_VER >= MC_1_20_1
|
||||||
if (event.getStage() == RenderLevelStageEvent.Stage.AFTER_LEVEL)
|
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)
|
if (event.getStage() == RenderLevelStageEvent.Stage.AFTER_SOLID_BLOCKS)
|
||||||
#else
|
#else
|
||||||
// FIXME: Is this the correct location for 1.16 & 1.17???
|
if (event.type.equals(TickEvent.RenderTickEvent.Type.RENDER))
|
||||||
// I couldnt find anything for rendering after the level, so is rendering after overlays ok?
|
|
||||||
if (event.type.equals(TickEvent.RenderTickEvent.Type.WORLD))
|
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
|||||||
@@ -19,184 +19,115 @@
|
|||||||
|
|
||||||
package com.seibel.distanthorizons.forge;
|
package com.seibel.distanthorizons.forge;
|
||||||
|
|
||||||
import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiAfterDhInitEvent;
|
import com.mojang.brigadier.CommandDispatcher;
|
||||||
import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiBeforeDhInitEvent;
|
import com.seibel.distanthorizons.common.AbstractModInitializer;
|
||||||
import com.seibel.distanthorizons.common.LodCommonMain;
|
|
||||||
import com.seibel.distanthorizons.common.forge.LodForgeMethodCaller;
|
|
||||||
import com.seibel.distanthorizons.common.wrappers.DependencySetup;
|
|
||||||
import com.seibel.distanthorizons.common.wrappers.gui.GetConfigScreen;
|
import com.seibel.distanthorizons.common.wrappers.gui.GetConfigScreen;
|
||||||
import com.seibel.distanthorizons.common.wrappers.minecraft.MinecraftClientWrapper;
|
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||||
import com.seibel.distanthorizons.core.jar.ModJarInfo;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IModChecker;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.AbstractOptifineAccessor;
|
|
||||||
import com.seibel.distanthorizons.coreapi.DependencyInjection.ApiEventInjector;
|
|
||||||
import com.seibel.distanthorizons.coreapi.ModInfo;
|
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.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 com.seibel.distanthorizons.forge.wrappers.modAccessor.OptifineAccessor;
|
||||||
|
|
||||||
import net.minecraft.client.renderer.block.model.BakedQuad;
|
import net.minecraft.commands.CommandSourceStack;
|
||||||
import net.minecraft.core.Direction;
|
import net.minecraft.server.MinecraftServer;
|
||||||
#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.minecraftforge.common.MinecraftForge;
|
import net.minecraftforge.common.MinecraftForge;
|
||||||
|
import net.minecraftforge.event.RegisterCommandsEvent;
|
||||||
import net.minecraftforge.fml.ModLoadingContext;
|
import net.minecraftforge.fml.ModLoadingContext;
|
||||||
import net.minecraftforge.fml.common.Mod;
|
import net.minecraftforge.fml.common.Mod;
|
||||||
import net.minecraftforge.fml.event.lifecycle.*;
|
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;
|
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
|
||||||
#if PRE_MC_1_17_1
|
#if MC_VER < MC_1_17_1
|
||||||
import net.minecraftforge.fml.ExtensionPoint;
|
import net.minecraftforge.fml.ExtensionPoint;
|
||||||
#elif MC_1_17_1
|
#elif MC_VER == MC_1_17_1
|
||||||
import net.minecraftforge.fmlclient.ConfigGuiHandler;
|
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;
|
import net.minecraftforge.client.ConfigGuiHandler;
|
||||||
#else
|
#else
|
||||||
import net.minecraftforge.client.ConfigScreenHandler;
|
import net.minecraftforge.client.ConfigScreenHandler;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
import org.apache.logging.log4j.Logger;
|
|
||||||
|
|
||||||
// these imports change due to forge refactoring classes in 1.19
|
// 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 net.minecraftforge.client.model.data.ModelDataMap;
|
||||||
|
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
#else
|
#else
|
||||||
import net.minecraft.client.renderer.RenderType;
|
|
||||||
import net.minecraftforge.client.model.data.ModelData;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
import java.lang.invoke.MethodHandles;
|
import java.util.function.Consumer;
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize and setup the Mod. <br>
|
* Initialize and setup the Mod. <br>
|
||||||
* If you are looking for the real start of the mod
|
* If you are looking for the real start of the mod
|
||||||
* check out the ClientProxy.
|
* check out the ClientProxy.
|
||||||
*
|
|
||||||
* @author coolGi
|
|
||||||
* @author Ran
|
|
||||||
* @author James Seibel
|
|
||||||
* @version 8-15-2022
|
|
||||||
*/
|
*/
|
||||||
@Mod(ModInfo.ID)
|
@Mod(ModInfo.ID)
|
||||||
public class ForgeMain implements LodForgeMethodCaller
|
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()
|
public ForgeMain()
|
||||||
{
|
{
|
||||||
DependencySetup.createClientBindings();
|
|
||||||
|
|
||||||
// initDedicated(null);
|
|
||||||
// initDedicated(null);
|
|
||||||
// Register the mod initializer (Actual event registration is done in the different proxies)
|
// Register the mod initializer (Actual event registration is done in the different proxies)
|
||||||
FMLJavaModLoadingContext.get().getModEventBus().addListener(this::initClient);
|
FMLJavaModLoadingContext.get().getModEventBus().addListener((FMLClientSetupEvent e) -> this.onInitializeClient());
|
||||||
FMLJavaModLoadingContext.get().getModEventBus().addListener(this::initDedicated);
|
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");
|
#if MC_VER < MC_1_17_1
|
||||||
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
|
|
||||||
ModLoadingContext.get().registerExtensionPoint(ExtensionPoint.CONFIGGUIFACTORY,
|
ModLoadingContext.get().registerExtensionPoint(ExtensionPoint.CONFIGGUIFACTORY,
|
||||||
() -> (client, parent) -> GetConfigScreen.getScreen(parent));
|
() -> (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,
|
ModLoadingContext.get().registerExtensionPoint(ConfigGuiHandler.ConfigGuiFactory.class,
|
||||||
() -> new ConfigGuiHandler.ConfigGuiFactory((client, parent) -> GetConfigScreen.getScreen(parent)));
|
() -> new ConfigGuiHandler.ConfigGuiFactory((client, parent) -> GetConfigScreen.getScreen(parent)));
|
||||||
#else
|
#else
|
||||||
ModLoadingContext.get().registerExtensionPoint(ConfigScreenHandler.ConfigScreenFactory.class,
|
ModLoadingContext.get().registerExtensionPoint(ConfigScreenHandler.ConfigScreenFactory.class,
|
||||||
() -> new ConfigScreenHandler.ConfigScreenFactory((client, parent) -> GetConfigScreen.getScreen(parent)));
|
() -> new ConfigScreenHandler.ConfigScreenFactory((client, parent) -> GetConfigScreen.getScreen(parent)));
|
||||||
#endif
|
#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
|
@Override
|
||||||
#if PRE_MC_1_19_2
|
protected void subscribeRegisterCommandsEvent(Consumer<CommandDispatcher<CommandSourceStack>> eventHandler)
|
||||||
public List<BakedQuad> getQuads(MinecraftClientWrapper mc, Block block, BlockState blockState, Direction direction, Random random)
|
|
||||||
{
|
{
|
||||||
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
|
@Override
|
||||||
public int colorResolverGetColor(ColorResolver resolver, Biome biome, double x, double z)
|
protected void subscribeClientStartedEvent(Runnable eventHandler)
|
||||||
{
|
{
|
||||||
#if MC_1_17_1______Still_needed
|
// FIXME What event is this?
|
||||||
return resolver.m_130045_(biome, x, z);
|
|
||||||
#else
|
|
||||||
return resolver.getColor(biome, x, z);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@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;
|
package com.seibel.distanthorizons.forge;
|
||||||
|
|
||||||
|
import com.seibel.distanthorizons.common.AbstractModInitializer;
|
||||||
import com.seibel.distanthorizons.common.util.ProxyUtil;
|
import com.seibel.distanthorizons.common.util.ProxyUtil;
|
||||||
import com.seibel.distanthorizons.common.wrappers.chunk.ChunkWrapper;
|
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.world.ServerLevelWrapper;
|
||||||
import com.seibel.distanthorizons.common.wrappers.worldGeneration.BatchGenerationEnvironment;
|
import com.seibel.distanthorizons.common.wrappers.worldGeneration.BatchGenerationEnvironment;
|
||||||
import com.seibel.distanthorizons.core.api.internal.ServerApi;
|
import com.seibel.distanthorizons.core.api.internal.ServerApi;
|
||||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.chunk.IChunkWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.chunk.IChunkWrapper;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper;
|
||||||
import net.minecraft.client.multiplayer.ClientLevel;
|
|
||||||
import net.minecraft.server.level.ServerLevel;
|
import net.minecraft.server.level.ServerLevel;
|
||||||
import net.minecraft.world.level.Level;
|
|
||||||
import net.minecraft.world.level.LevelAccessor;
|
import net.minecraft.world.level.LevelAccessor;
|
||||||
|
import net.minecraftforge.common.MinecraftForge;
|
||||||
import net.minecraftforge.event.TickEvent;
|
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.ChunkEvent;
|
||||||
import net.minecraftforge.event.world.WorldEvent;
|
import net.minecraftforge.event.world.WorldEvent;
|
||||||
#else
|
#else
|
||||||
@@ -23,10 +22,10 @@ import net.minecraftforge.event.level.LevelEvent;
|
|||||||
#endif
|
#endif
|
||||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
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.FMLServerAboutToStartEvent;
|
||||||
import net.minecraftforge.fml.event.server.FMLServerStoppingEvent;
|
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.FMLServerAboutToStartEvent;
|
||||||
import net.minecraftforge.fmlserverevents.FMLServerStoppingEvent;
|
import net.minecraftforge.fmlserverevents.FMLServerStoppingEvent;
|
||||||
#else
|
#else
|
||||||
@@ -39,9 +38,9 @@ import org.apache.logging.log4j.Logger;
|
|||||||
|
|
||||||
import java.util.function.Supplier;
|
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(); }
|
private static LevelAccessor GetEventLevel(WorldEvent e) { return e.getWorld(); }
|
||||||
#else
|
#else
|
||||||
private static LevelAccessor GetEventLevel(LevelEvent e) { return e.getLevel(); }
|
private static LevelAccessor GetEventLevel(LevelEvent e) { return e.getLevel(); }
|
||||||
@@ -53,6 +52,15 @@ public class ForgeServerProxy
|
|||||||
public static Supplier<Boolean> isGenerationThreadChecker = null;
|
public static Supplier<Boolean> isGenerationThreadChecker = null;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void registerEvents()
|
||||||
|
{
|
||||||
|
MinecraftForge.EVENT_BUS.register(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//=============//
|
//=============//
|
||||||
// constructor //
|
// constructor //
|
||||||
//=============//
|
//=============//
|
||||||
@@ -81,21 +89,21 @@ public class ForgeServerProxy
|
|||||||
|
|
||||||
// ServerWorldLoadEvent
|
// ServerWorldLoadEvent
|
||||||
@SubscribeEvent
|
@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);
|
this.serverApi.serverLoadEvent(this.isDedicated);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ServerWorldUnloadEvent
|
// ServerWorldUnloadEvent
|
||||||
@SubscribeEvent
|
@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();
|
this.serverApi.serverUnloadEvent();
|
||||||
}
|
}
|
||||||
|
|
||||||
// ServerLevelLoadEvent
|
// ServerLevelLoadEvent
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
#if PRE_MC_1_19_2
|
#if MC_VER < MC_1_19_2
|
||||||
public void serverLevelLoadEvent(WorldEvent.Load event)
|
public void serverLevelLoadEvent(WorldEvent.Load event)
|
||||||
#else
|
#else
|
||||||
public void serverLevelLoadEvent(LevelEvent.Load event)
|
public void serverLevelLoadEvent(LevelEvent.Load event)
|
||||||
@@ -109,7 +117,7 @@ public class ForgeServerProxy
|
|||||||
|
|
||||||
// ServerLevelUnloadEvent
|
// ServerLevelUnloadEvent
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
#if PRE_MC_1_19_2
|
#if MC_VER < MC_1_19_2
|
||||||
public void serverLevelUnloadEvent(WorldEvent.Unload event)
|
public void serverLevelUnloadEvent(WorldEvent.Unload event)
|
||||||
#else
|
#else
|
||||||
public void serverLevelUnloadEvent(LevelEvent.Unload event)
|
public void serverLevelUnloadEvent(LevelEvent.Unload event)
|
||||||
|
|||||||
@@ -14,10 +14,24 @@ import java.util.Set;
|
|||||||
*/
|
*/
|
||||||
public class ForgeMixinPlugin implements IMixinConfigPlugin
|
public class ForgeMixinPlugin implements IMixinConfigPlugin
|
||||||
{
|
{
|
||||||
|
private boolean firstRun = false;
|
||||||
|
private boolean isForgeMixinFile;
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean shouldApplyMixin(String targetClassName, String mixinClassName)
|
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 (mixinClassName.contains(".mods."))
|
||||||
{ // If the mixin wants to go into a mod then we check if that mod is loaded or not
|
{ // If the mixin wants to go into a mod then we check if that mod is loaded or not
|
||||||
return ModList.get().isLoaded(
|
return ModList.get().isLoaded(
|
||||||
@@ -28,44 +42,27 @@ public class ForgeMixinPlugin implements IMixinConfigPlugin
|
|||||||
.replaceAll("\\..*$", "") // Replaces everything after the mod name
|
.replaceAll("\\..*$", "") // Replaces everything after the mod name
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onLoad(String mixinPackage)
|
public void onLoad(String mixinPackage) { }
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getRefMapperConfig()
|
public String getRefMapperConfig() { return null; }
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void acceptTargets(Set<String> myTargets, Set<String> otherTargets)
|
public void acceptTargets(Set<String> myTargets, Set<String> otherTargets) { }
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<String> getMixins()
|
public List<String> getMixins() { return null; }
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void preApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo)
|
public void preApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) { }
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@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"))
|
@Inject(method = "handleLogin", at = @At("RETURN"))
|
||||||
void onHandleLoginEnd(CallbackInfo ci) { ClientApi.INSTANCE.onClientOnlyConnected(); }
|
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"))
|
@Inject(method = "cleanup", at = @At("HEAD"))
|
||||||
#else
|
#else
|
||||||
@Inject(method = "close", at = @At("HEAD"))
|
@Inject(method = "close", at = @At("HEAD"))
|
||||||
|
|||||||
+4
-4
@@ -35,7 +35,7 @@ import net.minecraft.client.renderer.FogRenderer.FogMode;
|
|||||||
import net.minecraft.world.effect.MobEffects;
|
import net.minecraft.world.effect.MobEffects;
|
||||||
import net.minecraft.world.entity.Entity;
|
import net.minecraft.world.entity.Entity;
|
||||||
import net.minecraft.world.entity.LivingEntity;
|
import net.minecraft.world.entity.LivingEntity;
|
||||||
#if PRE_MC_1_17_1
|
#if MC_VER < MC_1_17_1
|
||||||
import net.minecraft.world.level.material.FluidState;
|
import net.minecraft.world.level.material.FluidState;
|
||||||
#else
|
#else
|
||||||
import net.minecraft.world.level.material.FogType;
|
import net.minecraft.world.level.material.FogType;
|
||||||
@@ -53,10 +53,10 @@ public class MixinFogRenderer
|
|||||||
|
|
||||||
@Inject(at = @At("RETURN"),
|
@Inject(at = @At("RETURN"),
|
||||||
method = "setupFog(Lnet/minecraft/client/Camera;Lnet/minecraft/client/renderer/FogRenderer$FogMode;FZF)V",
|
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)
|
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();
|
FluidState fluidState = camera.getFluidInCamera();
|
||||||
boolean cameraNotInFluid = fluidState.isEmpty();
|
boolean cameraNotInFluid = fluidState.isEmpty();
|
||||||
#else
|
#else
|
||||||
@@ -71,7 +71,7 @@ public class MixinFogRenderer
|
|||||||
&& !SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class).isFogStateSpecial()
|
&& !SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class).isFogStateSpecial()
|
||||||
&& Config.Client.Advanced.Graphics.Fog.disableVanillaFog.get())
|
&& 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.fogStart(A_REALLY_REALLY_BIG_VALUE);
|
||||||
RenderSystem.fogEnd(A_EVEN_LARGER_VALUE);
|
RenderSystem.fogEnd(A_EVEN_LARGER_VALUE);
|
||||||
#else
|
#else
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user