Compare commits
377 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 27c3c0c404 | |||
| df7728707a | |||
| 6bd7f54a8e | |||
| 954175943d | |||
| a1e8af623d | |||
| af625d912a | |||
| 04d61e81ed | |||
| 78fc6be193 | |||
| 969dfa1dd0 | |||
| 19578f2104 | |||
| de60b15d2b | |||
| 7c5ffe3f10 | |||
| 2daf47f202 | |||
| 4644121fe3 | |||
| f75c9ec06a | |||
| e174939cf5 | |||
| b8ecbdd27d | |||
| 100401e0ac | |||
| a5f2ce79e4 | |||
| 4358360362 | |||
| 889fc7d7fe | |||
| 8fec85d4cb | |||
| de744d1f10 | |||
| 4e50099308 | |||
| e17f201e6b | |||
| 14fb775212 | |||
| 9742a2146a | |||
| 270476f4d2 | |||
| b1205c73d5 | |||
| 760019aac6 | |||
| a89df000d0 | |||
| 3278d3518d | |||
| 0f8bf01d30 | |||
| e4132fe469 | |||
| f593df5d1d | |||
| a42153dc14 | |||
| 7dbb17b339 | |||
| 4e226130df | |||
| abf5ec313a | |||
| 2257ceae53 | |||
| e330a7cd3b | |||
| 9316575534 | |||
| 3046127b03 | |||
| 7a4e784701 | |||
| 96a2b406aa | |||
| e2db3cdc5c | |||
| 99fa754e91 | |||
| be28eaf122 | |||
| cd05d5d811 | |||
| f6f7c1702a | |||
| b593293c05 | |||
| 1f1f44766d | |||
| 6ebd768d97 | |||
| bd75c7454c | |||
| 1c2fab1528 | |||
| 92a096a708 | |||
| e331def140 | |||
| 31c1e40ec1 | |||
| 8ced3f838d | |||
| b37bf72eb2 | |||
| c6485f5e92 | |||
| 4d2132cc08 | |||
| cb3dfd6786 | |||
| 0af836f2f5 | |||
| 509184f5ce | |||
| d788ded283 | |||
| 131e257739 | |||
| 9333c006b7 | |||
| 59ca964231 | |||
| 293942b7de | |||
| fce9a94b96 | |||
| a344389500 | |||
| 000d87ccdd | |||
| f241d849b7 | |||
| a315b1190a | |||
| a35a268670 | |||
| dff898e228 | |||
| 9ab67716bc | |||
| cc554991fe | |||
| 7366b543bd | |||
| 480f3d9563 | |||
| 991e4b8b20 | |||
| 2f6551904a | |||
| dc1ee3faaf | |||
| f96196a421 | |||
| 678eeaa3bf | |||
| 87dbda685b | |||
| 954dc49932 | |||
| 0c031588aa | |||
| 6e419b3120 | |||
| de0ddee3fb | |||
| 59fac2fa11 | |||
| ef0d3b3957 | |||
| f34be62af4 | |||
| 151ee93842 | |||
| c89757aa5d | |||
| 2617fcfab1 | |||
| 0528a2d423 | |||
| aa62921986 | |||
| f39ae98a48 | |||
| e10e51ae26 | |||
| 758e941da9 | |||
| 34777b1672 | |||
| a8156d90d8 | |||
| 45527ada14 | |||
| b6b98b1c00 | |||
| d7b98c9762 | |||
| fc9faeb6e5 | |||
| c965fb41b9 | |||
| 379a09b9c9 | |||
| da0b34b2dc | |||
| 6153b68302 | |||
| 3fc60909d2 | |||
| a20ab505ef | |||
| 8f412d5dc7 | |||
| bb7e993d10 | |||
| 8aeceb717c | |||
| 1b2fc0e364 | |||
| 2bf6b59419 | |||
| 5e6080da78 | |||
| a4a23121c8 | |||
| fa6e36cb44 | |||
| 64eb773ab8 | |||
| 841e831ce0 | |||
| 427b54b1eb | |||
| 00e831c8f3 | |||
| a5d5168b07 | |||
| 521dfb83e4 | |||
| d414a27498 | |||
| 7e8ce1c695 | |||
| 302a894cb3 | |||
| 0c213aa860 | |||
| 142deb47cb | |||
| 4390b1c694 | |||
| c26f196318 | |||
| 4cae95a942 | |||
| d07219758f | |||
| 051b2e31b9 | |||
| 6e0ea18ca3 | |||
| 407d633a6c | |||
| a4ae25886a | |||
| ae02066093 | |||
| fd4f628618 | |||
| b389b144c1 | |||
| 95e929220a | |||
| 3d6d2a62f9 | |||
| 60d8d0be50 | |||
| 18f5c6aa95 | |||
| 13f28a9bd8 | |||
| 640c6b8a9c | |||
| 69202b86cd | |||
| 330bab0616 | |||
| c77d0bab6d | |||
| 7ef14602f5 | |||
| 762ef42a48 | |||
| ba07a4188b | |||
| 4a6387b383 | |||
| b7254c7d12 | |||
| 8873503853 | |||
| 430b23bb45 | |||
| 1c785fded8 | |||
| f2bfc50a31 | |||
| 17ffa3eaba | |||
| a6805eeb9a | |||
| b3d7623276 | |||
| df5e61f4bd | |||
| 8cd841220d | |||
| fd5fd05622 | |||
| 6769702d45 | |||
| 2ce16a0594 | |||
| cd2f2c4ae5 | |||
| 0f4e9792d2 | |||
| cf1be5f3ba | |||
| f2c919725a | |||
| 5e5b218e14 | |||
| 0d18b38434 | |||
| 3838f06723 | |||
| d255e08204 | |||
| c2feac4642 | |||
| 93f2605c6d | |||
| c1c80f1000 | |||
| 7555073c14 | |||
| fa607062fa | |||
| 8bfe624f97 | |||
| 32a5880c17 | |||
| d51d403906 | |||
| 1fb42f3c8e | |||
| 87fdfc5048 | |||
| 5f7de8ff5b | |||
| 3e6a2314bd | |||
| deebd9a8cf | |||
| 3e71f31f8e | |||
| f7d4642a44 | |||
| 59a6cae353 | |||
| ef53a299f9 | |||
| c5def9b663 | |||
| 71860612af | |||
| 354a3c6133 | |||
| bc49bfe2ba | |||
| c0e48a29a5 | |||
| 363f865168 | |||
| d6ceeee2a3 | |||
| f6dc7492f9 | |||
| 4b4b1f0ddc | |||
| e5524edc4a | |||
| 75de1e5fd1 | |||
| 9c1c6d3503 | |||
| ee55f066a9 | |||
| e06889a322 | |||
| 7dd26b110b | |||
| de7dbcb622 | |||
| 9678be05a8 | |||
| db8581da57 | |||
| f7423af5f4 | |||
| 518fcfca97 | |||
| ecdada10c0 | |||
| 7ffdf6f514 | |||
| 2b8aea39d7 | |||
| 502d3424b0 | |||
| 33748510fe | |||
| 9f55203d69 | |||
| 241dd14431 | |||
| bf5fded327 | |||
| 7423b9577d | |||
| 54a3c5750e | |||
| 1bf8317398 | |||
| 5a0d7b0d67 | |||
| 64b0e312f3 | |||
| d22aab08cb | |||
| 0368342336 | |||
| 0ccae5ebbc | |||
| e5a8464647 | |||
| 6acb4d4184 | |||
| 2798368099 | |||
| bcdce2bdf5 | |||
| 43773652aa | |||
| 10072200b5 | |||
| a00647f8e7 | |||
| 96429eec00 | |||
| c49e38a58c | |||
| b2047ce0c0 | |||
| 5b60d515e9 | |||
| cf0205caa4 | |||
| c91ab1deb1 | |||
| 2b5dd236aa | |||
| 0658479921 | |||
| ff8b07ac12 | |||
| fb87ee529a | |||
| 1fabc24e45 | |||
| 9ab2cfcb6a | |||
| e81e31fc24 | |||
| e69b7dec7d | |||
| 534e4a4377 | |||
| 3193773583 | |||
| 4d4906228e | |||
| e4a1d7478a | |||
| cf8eaa57cf | |||
| 2211add5e0 | |||
| e432358e1b | |||
| 3ccce80e1d | |||
| 1952f91540 | |||
| 0e1017111e | |||
| b4be8ab83f | |||
| 3b807dae95 | |||
| 9fdaeed69b | |||
| b7d627f0f5 | |||
| 733bbc0b58 | |||
| 17f6147e13 | |||
| 08c4c8667a | |||
| 526791aae7 | |||
| 8fdd6dcccc | |||
| fb4f5819fd | |||
| 58554f3891 | |||
| 5020084663 | |||
| 5aaab01ac9 | |||
| 024f60de9b | |||
| 1ccc46869d | |||
| 3edcb8d03d | |||
| d7189f0f05 | |||
| f19aa7831e | |||
| 601eeb7fbe | |||
| a8f20a407b | |||
| 872a7d9fa8 | |||
| 310b85ad83 | |||
| b8d94ba7eb | |||
| 4c112aa8ae | |||
| df6da4b48a | |||
| c3e8449979 | |||
| d8707bfe01 | |||
| f07940c11f | |||
| 889c3d32c9 | |||
| 1e502c5933 | |||
| f01e31f475 | |||
| 4285f32b94 | |||
| af5bcafa45 | |||
| 909870b321 | |||
| 2b5dd8b77e | |||
| 4d4e4a9706 | |||
| ac82e90dc2 | |||
| 8063141406 | |||
| 5c17e9599b | |||
| 2e54f2166d | |||
| a0bd2ba4a1 | |||
| 38102ac17f | |||
| 139c5869c9 | |||
| 79206420f9 | |||
| e046b972ca | |||
| ea4949b3a2 | |||
| 05d5f0b943 | |||
| 81df84dc37 | |||
| ff9bab99c7 | |||
| 301ea26a03 | |||
| bd7a03b0ca | |||
| 4e0619a269 | |||
| 8b13afeb23 | |||
| ce44feeb40 | |||
| 821e86b875 | |||
| 015e596eda | |||
| 09e535abf4 | |||
| 855f7f0f9a | |||
| 5fa3e3cb7f | |||
| 0bddc2dcac | |||
| 42a8e0e0f0 | |||
| 7b77e07a7d | |||
| db17d27823 | |||
| 362b800f25 | |||
| 29e26d659d | |||
| afa658cc00 | |||
| cde0d466dd | |||
| 4031b55630 | |||
| 86e07156d1 | |||
| 1e8df274ee | |||
| f0153cc4a6 | |||
| 3044c238fd | |||
| ead58390cd | |||
| 504d22ff37 | |||
| cc42f8667f | |||
| 6135b3ce7f | |||
| 3c8efa17d5 | |||
| dccae0aea0 | |||
| 2728236ced | |||
| 76ce1d6b21 | |||
| 94ddebaec0 | |||
| cec165176b | |||
| 99ad837441 | |||
| f8be132ba2 | |||
| 122f5431a6 | |||
| c2884954a4 | |||
| 3a0453c8c5 | |||
| 9d241ab175 | |||
| ee7eed8d3c | |||
| 1125452a8f | |||
| a3712c8f72 | |||
| e2022fab2d | |||
| bcea1be19b | |||
| 8d799203c5 | |||
| 980ce2f2af | |||
| c6bea3faa3 | |||
| 7707f55b25 | |||
| f087bb7182 | |||
| bf269c9abf | |||
| a8c7405f9d | |||
| 43c9232e7e | |||
| 8351c58d7b | |||
| aa86381b80 | |||
| 563840ca58 | |||
| b5b9b688c3 | |||
| 3731223087 | |||
| 72d770c0f3 | |||
| ee4b83fa99 | |||
| ee6e3a9876 | |||
| f84570a6fc | |||
| a0f5af46a2 | |||
| 18074f15f5 | |||
| bba0424c6d | |||
| 282f6cfbb8 | |||
| b97b1b61b7 |
+9
-29
@@ -1,31 +1,3 @@
|
|||||||
# eclipse
|
|
||||||
bin
|
|
||||||
*.launch
|
|
||||||
.settings
|
|
||||||
.metadata
|
|
||||||
.classpath
|
|
||||||
.project
|
|
||||||
|
|
||||||
# idea
|
|
||||||
out
|
|
||||||
*.ipr
|
|
||||||
*.iws
|
|
||||||
*.iml
|
|
||||||
.idea
|
|
||||||
|
|
||||||
# gradle
|
|
||||||
build
|
|
||||||
.gradle
|
|
||||||
|
|
||||||
# other
|
|
||||||
eclipse
|
|
||||||
run
|
|
||||||
|
|
||||||
# Files from Forge MDK
|
|
||||||
logs
|
|
||||||
forge*changelog.txt
|
|
||||||
|
|
||||||
.architectury-transformer/
|
|
||||||
build/
|
build/
|
||||||
*.ipr
|
*.ipr
|
||||||
run/
|
run/
|
||||||
@@ -36,6 +8,7 @@ out/
|
|||||||
output/
|
output/
|
||||||
bin/
|
bin/
|
||||||
libs/
|
libs/
|
||||||
|
.architectury-transformer/
|
||||||
|
|
||||||
.classpath
|
.classpath
|
||||||
.project
|
.project
|
||||||
@@ -45,9 +18,16 @@ classes/
|
|||||||
.vscode
|
.vscode
|
||||||
.settings
|
.settings
|
||||||
*.launch
|
*.launch
|
||||||
|
hs_err_pid*
|
||||||
|
|
||||||
**/src/generated/
|
**/src/generated/
|
||||||
Merged/
|
Merged/
|
||||||
|
|
||||||
# file from notepad++
|
# file from notepad++
|
||||||
*.bak
|
*.bak
|
||||||
|
|
||||||
|
# file genearated via MC version switching using preprocessor
|
||||||
|
build.properties
|
||||||
|
|
||||||
|
# This accesswidener is generated at runtime ant not needed
|
||||||
|
common/src/main/resources/lod.accesswidener
|
||||||
|
|||||||
+146
-54
@@ -1,15 +1,18 @@
|
|||||||
# use Eclipse's JDK
|
# use Eclipse's JDK
|
||||||
image: gradle:eclipse-temurin
|
image: gradle:eclipse-temurin
|
||||||
|
# The ci should always use an unix/unix-like OS to work
|
||||||
|
|
||||||
# all stages need to be defined here
|
# all stages need to be defined here
|
||||||
|
# Don't build the standalone jar yet because it isn't done yet
|
||||||
|
# - build_standalone
|
||||||
stages:
|
stages:
|
||||||
- build_18-1
|
- build_19
|
||||||
- build_18-2
|
- build_18_2
|
||||||
# - zip_artifacts
|
- build_18_1
|
||||||
|
- build_17_1
|
||||||
|
- build_16_5
|
||||||
|
|
||||||
variables:
|
variables:
|
||||||
# If we have correctness issues when compiling this can be set to false
|
|
||||||
GRADLE_OPTS: "-Dorg.gradle.daemon=true"
|
|
||||||
# Pull core when building
|
# Pull core when building
|
||||||
GIT_SUBMODULE_STRATEGY: recursive
|
GIT_SUBMODULE_STRATEGY: recursive
|
||||||
|
|
||||||
@@ -20,59 +23,147 @@ before_script:
|
|||||||
- echo GE_JOB_ID=$CI_JOB_ID >> generate_jars.env
|
- echo GE_JOB_ID=$CI_JOB_ID >> generate_jars.env
|
||||||
|
|
||||||
|
|
||||||
# 1.18.1 build
|
# The standalone build
|
||||||
build_18-1:
|
#build_standalone:
|
||||||
stage: build_18-1
|
# stage: build_standalone
|
||||||
script: ./gradlew build -PmcVer=1.18.1 --gradle-user-home cache/; ./gradlew merge --gradle-user-home cache/
|
# script:
|
||||||
# build using Java 17
|
# # make sure any previously merged jars are removed before running this job.
|
||||||
image: eclipse-temurin:17
|
# # note: if the merged folder doesn't exist "rm -R Merged" will throw an error, which can be ignored
|
||||||
cache:
|
# # the "|| true" makes that step always succeed.
|
||||||
key: "$CI_COMMIT_REF_NAME_18-1"
|
# - ./gradlew core:build --gradle-user-home cache/;
|
||||||
policy: pull-push
|
#
|
||||||
paths:
|
# # Copy the file with the shortest name to the root DistantHorizons.jar so it can be sent off
|
||||||
- .gradle
|
# - cp $(find core/build/libs/ | awk 'function base(f){sub(".*/", "", f); return f;} {print length(base($0)), $0}'| sort -n | head -2 | grep -P "[0-9][0-9] core/build/libs/*" | #sed -r "s/([0-9][0-9] )//g") DistantHorizons.jar
|
||||||
- cache/
|
# # build using Java 16
|
||||||
|
# image: eclipse-temurin:16
|
||||||
|
# artifacts:
|
||||||
|
# name: "NightlyBuild_standalone-${CI_COMMIT_SHORT_SHA}-${CI_COMMIT_TIMESTAMP}"
|
||||||
|
# paths:
|
||||||
|
# # Get the standalone jar
|
||||||
|
# - DistantHorizons.jar
|
||||||
|
# expire_in: 1 day
|
||||||
|
# # even if one build fails, upload the successful jars
|
||||||
|
# when: always
|
||||||
|
# cache:
|
||||||
|
# key: "gradleCache"
|
||||||
|
# policy: pull-push
|
||||||
|
# paths:
|
||||||
|
# - .gradle
|
||||||
|
# - cache/
|
||||||
|
# allow_failure: true
|
||||||
|
|
||||||
|
|
||||||
|
# 1.16.5 build
|
||||||
|
build_16_5:
|
||||||
|
stage: build_16_5
|
||||||
|
script:
|
||||||
|
# make sure any previously merged jars are removed before running this job.
|
||||||
|
# note: if the merged folder doesn't exist "rm -R Merged" will throw an error, which can be ignored
|
||||||
|
# the "|| true" makes that step always succeed.
|
||||||
|
- ./gradlew test --gradle-user-home cache/;
|
||||||
|
- ./gradlew build -PmcVer="1.16.5" --gradle-user-home cache/;
|
||||||
|
# build using Java 16
|
||||||
|
image: eclipse-temurin:16
|
||||||
|
artifacts:
|
||||||
|
name: "Merged_NightlyBuild_1_16_5-${CI_COMMIT_SHORT_SHA}-${CI_COMMIT_TIMESTAMP}"
|
||||||
|
paths:
|
||||||
|
# relative to the root directory
|
||||||
|
- Merged
|
||||||
|
expire_in: 1 day
|
||||||
|
# even if one build fails, upload the successful jars
|
||||||
|
when: always
|
||||||
|
cache:
|
||||||
|
key: "gradleCache"
|
||||||
|
policy: pull-push
|
||||||
|
paths:
|
||||||
|
- .gradle
|
||||||
|
- cache/
|
||||||
|
allow_failure: true
|
||||||
|
|
||||||
|
# 1.17.1 build
|
||||||
|
build_17_1:
|
||||||
|
stage: build_17_1
|
||||||
|
script:
|
||||||
|
- ./gradlew test --gradle-user-home cache/;
|
||||||
|
- ./gradlew build -PmcVer="1.17.1" --gradle-user-home cache/;
|
||||||
|
image: eclipse-temurin:16
|
||||||
|
artifacts:
|
||||||
|
name: "Merged_NightlyBuild_1_17_1-${CI_COMMIT_SHORT_SHA}-${CI_COMMIT_TIMESTAMP}"
|
||||||
|
paths:
|
||||||
|
- Merged
|
||||||
|
expire_in: 1 day
|
||||||
|
when: always
|
||||||
|
cache:
|
||||||
|
key: "gradleCache"
|
||||||
|
policy: pull-push
|
||||||
|
paths:
|
||||||
|
- .gradle
|
||||||
|
- cache/
|
||||||
|
allow_failure: true
|
||||||
|
|
||||||
|
# 1.18.1 build
|
||||||
|
build_18_1:
|
||||||
|
stage: build_18_1
|
||||||
|
script:
|
||||||
|
- ./gradlew test --gradle-user-home cache/;
|
||||||
|
- ./gradlew build -PmcVer="1.18.1" --gradle-user-home cache/;
|
||||||
|
# build using Java 17
|
||||||
|
image: eclipse-temurin:17
|
||||||
|
artifacts:
|
||||||
|
name: "Merged_NightlyBuild_1_18_1-${CI_COMMIT_SHORT_SHA}-${CI_COMMIT_TIMESTAMP}"
|
||||||
|
paths:
|
||||||
|
- Merged
|
||||||
|
expire_in: 1 day
|
||||||
|
when: always
|
||||||
|
cache:
|
||||||
|
key: "gradleCache"
|
||||||
|
policy: pull-push
|
||||||
|
paths:
|
||||||
|
- .gradle
|
||||||
|
- cache/
|
||||||
|
allow_failure: true
|
||||||
|
|
||||||
# 1.18.2 build
|
# 1.18.2 build
|
||||||
build_18-2:
|
build_18_2:
|
||||||
stage: build_18-2
|
stage: build_18_2
|
||||||
script: ./gradlew build -PmcVer=1.18.2 --gradle-user-home cache/; ./gradlew merge --gradle-user-home cache/
|
script:
|
||||||
# build using Java 17
|
- ./gradlew test --gradle-user-home cache/;
|
||||||
image: eclipse-temurin:17
|
- ./gradlew build -PmcVer="1.18.2" --gradle-user-home cache/;
|
||||||
cache:
|
image: eclipse-temurin:17
|
||||||
key: "$CI_COMMIT_REF_NAME_18-2"
|
artifacts:
|
||||||
policy: pull-push
|
name: "Merged_NightlyBuild_1_18_2-${CI_COMMIT_SHORT_SHA}-${CI_COMMIT_TIMESTAMP}"
|
||||||
paths:
|
paths:
|
||||||
- .gradle
|
- Merged
|
||||||
- cache/
|
expire_in: 1 day
|
||||||
|
when: always
|
||||||
# TEMPORARY, there should be a way of either generating artifacts per build or in a separate stage
|
cache:
|
||||||
artifacts:
|
key: "gradleCache"
|
||||||
# This should only be done after the last build, otherwise there will be duplicate jars
|
policy: pull-push
|
||||||
name: "Merged_NightlyBuild-${CI_COMMIT_SHORT_SHA}-${CI_COMMIT_TIMESTAMP}"
|
paths:
|
||||||
paths:
|
- .gradle
|
||||||
# relative to the root directory
|
- cache/
|
||||||
- Merged
|
allow_failure: true
|
||||||
expire_in: 1 day
|
|
||||||
|
|
||||||
|
|
||||||
# # put artifacts in a zip
|
|
||||||
# # This should only be done after all the builds have been completed
|
|
||||||
# zip_artifacts:
|
|
||||||
# stage: zip_artifacts
|
|
||||||
# # The complier complains if we don't do something with the script line
|
|
||||||
# script: echo 'Building complete. Creating artifact Zip.'
|
|
||||||
# # build using Java 17
|
|
||||||
# image: eclipse-temurin:17
|
|
||||||
# artifacts:
|
|
||||||
# # This should only be done after the last build, otherwise there will be duplicate jars
|
|
||||||
# name: "Merged_NightlyBuild-${CI_COMMIT_SHORT_SHA}-${CI_COMMIT_TIMESTAMP}"
|
|
||||||
# paths:
|
|
||||||
# # relative to the root directory
|
|
||||||
# - Merged
|
|
||||||
# expire_in: 1 day
|
|
||||||
|
|
||||||
|
# 1.19 build
|
||||||
|
build_19:
|
||||||
|
stage: build_19
|
||||||
|
script:
|
||||||
|
- ./gradlew test --gradle-user-home cache/;
|
||||||
|
- ./gradlew build -PmcVer="1.19" --gradle-user-home cache/;
|
||||||
|
image: eclipse-temurin:17
|
||||||
|
artifacts:
|
||||||
|
name: "Merged_NightlyBuild_1_19-${CI_COMMIT_SHORT_SHA}-${CI_COMMIT_TIMESTAMP}"
|
||||||
|
paths:
|
||||||
|
- Merged
|
||||||
|
expire_in: 1 day
|
||||||
|
when: always
|
||||||
|
cache:
|
||||||
|
key: "gradleCache"
|
||||||
|
policy: pull-push
|
||||||
|
paths:
|
||||||
|
- .gradle
|
||||||
|
- cache/
|
||||||
|
allow_failure: true
|
||||||
|
|
||||||
|
|
||||||
# unused deployment stage
|
# unused deployment stage
|
||||||
@@ -98,3 +189,4 @@ build_18-2:
|
|||||||
# url: 'https://gitlab.com/jeseibel/minecraft-lod-mod/cw/-/jobs/${GE_JOB_ID}/artifacts/file/fabric/build/libs'
|
# url: 'https://gitlab.com/jeseibel/minecraft-lod-mod/cw/-/jobs/${GE_JOB_ID}/artifacts/file/fabric/build/libs'
|
||||||
# - name: 'Forge Jars'
|
# - name: 'Forge Jars'
|
||||||
# url: 'https://gitlab.com/jeseibel/minecraft-lod-mod/cw/-/jobs/${GE_JOB_ID}/artifacts/file/forge/build/libs'
|
# url: 'https://gitlab.com/jeseibel/minecraft-lod-mod/cw/-/jobs/${GE_JOB_ID}/artifacts/file/forge/build/libs'
|
||||||
|
|
||||||
|
|||||||
+2
-3
@@ -1,4 +1,3 @@
|
|||||||
[submodule "core"]
|
[submodule "coreSubProjects"]
|
||||||
path = core
|
path = coreSubProjects
|
||||||
url = https://gitlab.com/jeseibel/distant-horizons-core.git
|
url = https://gitlab.com/jeseibel/distant-horizons-core.git
|
||||||
branch = main
|
|
||||||
|
|||||||
@@ -0,0 +1,44 @@
|
|||||||
|
# 1.16.5 version
|
||||||
|
|
||||||
|
java_version=8
|
||||||
|
minecraft_version=1.16.5
|
||||||
|
parchment_version=2022.03.06
|
||||||
|
compatible_minecraft_versions=["1.16.4", "1.16.5"]
|
||||||
|
|
||||||
|
# Fabric loader
|
||||||
|
fabric_loader_version=0.13.2
|
||||||
|
fabric_api_version=0.42.0+1.16
|
||||||
|
architectury_version=1.31.61
|
||||||
|
# Fabric mod versions
|
||||||
|
modmenu_version=1.16.22
|
||||||
|
starlight_version_fabric=
|
||||||
|
phosphor_version_fabric=
|
||||||
|
lithium_version=mc1.16.5-0.6.6
|
||||||
|
sodium_version=mc1.16.5-0.2.0
|
||||||
|
iris_version=1.16.x-v1.2.5
|
||||||
|
bclib_version=
|
||||||
|
immersive_portals_version =
|
||||||
|
|
||||||
|
# Fabric mod run
|
||||||
|
# 0 = Dont enable and dont run
|
||||||
|
# 1 = Can be refranced in code but dosnt run
|
||||||
|
# 2 = Can be refranced in code and runs in client
|
||||||
|
enable_starlight=0
|
||||||
|
enable_phosphor=0
|
||||||
|
enable_lithium=0
|
||||||
|
enable_sodium=1
|
||||||
|
enable_iris=0
|
||||||
|
enable_bclib=0
|
||||||
|
|
||||||
|
# Forge loader
|
||||||
|
forge_version=36.2.28
|
||||||
|
# Forge mod versions
|
||||||
|
starlight_version_forge=
|
||||||
|
terraforged_version=3285909
|
||||||
|
|
||||||
|
# Forge mod run
|
||||||
|
# 0 = Dont enable and dont run
|
||||||
|
# 1 = Can be refranced in code but dosnt run
|
||||||
|
# 2 = Can be refranced in code and runs in client
|
||||||
|
enable_starlight_forge=0
|
||||||
|
enable_terraforged=2
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
# 1.17.1 version
|
||||||
|
|
||||||
|
java_version=16
|
||||||
|
minecraft_version=1.17.1
|
||||||
|
parchment_version=2021.12.12
|
||||||
|
compatible_minecraft_versions=["1.17", "1.17.1"]
|
||||||
|
|
||||||
|
# Fabric loader
|
||||||
|
fabric_loader_version=0.13.2
|
||||||
|
fabric_api_version=0.46.1+1.17
|
||||||
|
architectury_version=2.10.9
|
||||||
|
# Fabric mod versions
|
||||||
|
modmenu_version=2.0.14
|
||||||
|
starlight_version_fabric=3442770
|
||||||
|
phosphor_version_fabric=
|
||||||
|
lithium_version=mc1.17.1-0.7.5
|
||||||
|
sodium_version=mc1.17.1-0.3.4
|
||||||
|
iris_version=1.17.x-v1.2.5
|
||||||
|
bclib_version=
|
||||||
|
immersive_portals_version = 0.14-1.17
|
||||||
|
|
||||||
|
# Fabric mod run
|
||||||
|
# 0 = Dont enable and dont run
|
||||||
|
# 1 = Can be refranced in code but dosnt run
|
||||||
|
# 2 = Can be refranced in code and runs in client
|
||||||
|
enable_starlight=0
|
||||||
|
enable_phosphor=0
|
||||||
|
enable_lithium=0
|
||||||
|
enable_sodium=1
|
||||||
|
enable_iris=0
|
||||||
|
enable_bclib=0
|
||||||
|
|
||||||
|
# Forge loader
|
||||||
|
forge_version=37.1.1
|
||||||
|
# Forge mod versions
|
||||||
|
starlight_version_forge=3457784
|
||||||
|
terraforged_version=
|
||||||
|
|
||||||
|
# Forge mod run
|
||||||
|
# 0 = Dont enable and dont run
|
||||||
|
# 1 = Can be refranced in code but dosnt run
|
||||||
|
# 2 = Can be refranced in code and runs in client
|
||||||
|
enable_starlight_forge=0
|
||||||
|
enable_terraforged=0
|
||||||
+11
-4
@@ -1,17 +1,21 @@
|
|||||||
# 1.18.1 version based stuff
|
# 1.18.1 version
|
||||||
|
|
||||||
minecraft_version=1.18.1
|
|
||||||
java_version = 17
|
java_version = 17
|
||||||
|
minecraft_version=1.18.1
|
||||||
|
parchment_version=2022.03.06
|
||||||
|
compatible_minecraft_versions=["1.18", "1.18.1"]
|
||||||
|
|
||||||
# Fabric loader
|
# Fabric loader
|
||||||
fabric_loader_version=0.13.3
|
fabric_loader_version=0.13.3
|
||||||
fabric_api_version=0.46.6+1.18
|
fabric_api_version=0.46.6+1.18
|
||||||
|
architectury_version=3.9.57
|
||||||
# Fabric mod versions
|
# Fabric mod versions
|
||||||
modmenu_version=3.0.1
|
modmenu_version=3.0.1
|
||||||
starlight_version_fabric=3554912
|
starlight_version_fabric=3554912
|
||||||
|
phosphor_version_fabric=3573395
|
||||||
lithium_version=mc1.18.1-0.7.7
|
lithium_version=mc1.18.1-0.7.7
|
||||||
sodium_version=3605309
|
sodium_version=mc1.18.1-0.4.0-alpha6
|
||||||
iris_version=1.18.x-v1.1.4
|
iris_version=1.18.x-v1.2.5
|
||||||
bclib_version=1.2.5
|
bclib_version=1.2.5
|
||||||
immersive_portals_version = v1.0.4-1.18
|
immersive_portals_version = v1.0.4-1.18
|
||||||
|
|
||||||
@@ -20,6 +24,7 @@ fabric_api_version=0.46.6+1.18
|
|||||||
# 1 = Can be referenced in code but doesn't run
|
# 1 = Can be referenced in code but doesn't run
|
||||||
# 2 = Can be referenced in code and runs in client
|
# 2 = Can be referenced in code and runs in client
|
||||||
enable_starlight=0
|
enable_starlight=0
|
||||||
|
enable_phosphor=0
|
||||||
enable_sodium=1
|
enable_sodium=1
|
||||||
enable_lithium=0
|
enable_lithium=0
|
||||||
enable_iris=0
|
enable_iris=0
|
||||||
@@ -29,9 +34,11 @@ fabric_api_version=0.46.6+1.18
|
|||||||
forge_version=39.1.2
|
forge_version=39.1.2
|
||||||
# Forge mod versions
|
# Forge mod versions
|
||||||
starlight_version_forge=3559934
|
starlight_version_forge=3559934
|
||||||
|
terraforged_version=
|
||||||
|
|
||||||
# Forge mod run
|
# Forge mod run
|
||||||
# 0 = Dont enable and don't run
|
# 0 = Dont enable and don't run
|
||||||
# 1 = Can be referenced in code but doesn't run
|
# 1 = Can be referenced in code but doesn't run
|
||||||
# 2 = Can be referenced in code and runs in client
|
# 2 = Can be referenced in code and runs in client
|
||||||
enable_starlight_forge=0
|
enable_starlight_forge=0
|
||||||
|
enable_terraforged=0
|
||||||
|
|||||||
+18
-10
@@ -1,38 +1,46 @@
|
|||||||
# 1.18.2 version based stuff
|
# 1.18.2 version based stuff
|
||||||
# architectury_plugin_version = 3.4-SNAPSHOT
|
|
||||||
# dev_architectury_loom_version = 0.10.0-SNAPSHOT
|
|
||||||
minecraft_version=1.18.2
|
|
||||||
java_version = 17
|
java_version = 17
|
||||||
|
minecraft_version=1.18.2
|
||||||
|
parchment_version=2022.03.13
|
||||||
|
compatible_minecraft_versions=["1.18.2"]
|
||||||
|
|
||||||
# Fabric loader
|
# Fabric loader
|
||||||
fabric_loader_version=0.13.3
|
fabric_loader_version=0.13.3
|
||||||
fabric_api_version=0.48.0+1.18.2
|
fabric_api_version=0.48.0+1.18.2
|
||||||
|
architectury_version=4.4.59
|
||||||
# Fabric mod versions
|
# Fabric mod versions
|
||||||
modmenu_version=3.1.0
|
modmenu_version=3.1.0
|
||||||
starlight_version_fabric=3667443
|
starlight_version_fabric=3667443
|
||||||
|
phosphor_version_fabric=3573395
|
||||||
lithium_version=mc1.18.2-0.7.9
|
lithium_version=mc1.18.2-0.7.9
|
||||||
sodium_version=3669187
|
sodium_version=mc1.18.2-0.4.1
|
||||||
iris_version=1.18.x-v1.2.2
|
iris_version=1.18.x-v1.2.5
|
||||||
immersive_portals_version = v1.0.4-1.18
|
bclib_version=1.4.5
|
||||||
bclib_version=0
|
canvas_version=mc118:1.0.2397
|
||||||
|
immersive_portals_version = v1.4.9-1.18
|
||||||
|
|
||||||
# Fabric mod run
|
# Fabric mod run
|
||||||
# 0 = Don't enable and don't run
|
# 0 = Don't enable and don't run
|
||||||
# 1 = Can be referenced in code but doesn't run
|
# 1 = Can be referenced in code but doesn't run
|
||||||
# 2 = Can be referenced in code and runs in client
|
# 2 = Can be referenced in code and runs in client
|
||||||
enable_starlight=0
|
enable_starlight=0
|
||||||
|
enable_phosphor=0
|
||||||
enable_sodium=1
|
enable_sodium=1
|
||||||
enable_lithium=0
|
enable_lithium=0
|
||||||
enable_iris=0
|
enable_iris=0
|
||||||
enable_bclib=0
|
enable_bclib=1
|
||||||
|
enable_canvas=0
|
||||||
|
|
||||||
# Forge loader
|
# Forge loader
|
||||||
forge_version=40.0.18
|
forge_version=40.0.18
|
||||||
# Forge mod versions
|
# Forge mod versions
|
||||||
starlight_version_forge=0
|
starlight_version_forge=
|
||||||
|
terraforged_version=
|
||||||
|
|
||||||
# Forge mod run
|
# Forge mod run
|
||||||
# 0 = Dont enable and don't run
|
# 0 = Don't enable and don't run
|
||||||
# 1 = Can be referenced in code but doesn't run
|
# 1 = Can be referenced in code but doesn't run
|
||||||
# 2 = Can be referenced in code and runs in client
|
# 2 = Can be referenced in code and runs in client
|
||||||
enable_starlight_forge=0
|
enable_starlight_forge=0
|
||||||
|
enable_terraforged=0
|
||||||
|
|||||||
@@ -0,0 +1,45 @@
|
|||||||
|
java_version = 17
|
||||||
|
minecraft_version=1.19.2
|
||||||
|
parchment_version=2022.08.10
|
||||||
|
compatible_minecraft_versions=["1.19.2"]
|
||||||
|
|
||||||
|
# Fabric loader
|
||||||
|
fabric_loader_version=0.14.9
|
||||||
|
fabric_api_version=0.60.0+1.19.2
|
||||||
|
architectury_version=6.2.46
|
||||||
|
# Fabric mod versions
|
||||||
|
modmenu_version=4.0.6
|
||||||
|
starlight_version_fabric=
|
||||||
|
phosphor_version_fabric=
|
||||||
|
lithium_version=
|
||||||
|
sodium_version=mc1.19.2-0.4.4
|
||||||
|
iris_version=1.19.2-v1.3.1
|
||||||
|
bclib_version=1.4.5
|
||||||
|
immersive_portals_version =
|
||||||
|
canvas_version=mc119-1.0.2480
|
||||||
|
|
||||||
|
# Fabric mod run
|
||||||
|
# 0 = Don't enable and don't run
|
||||||
|
# 1 = Can be referenced in code but doesn't run
|
||||||
|
# 2 = Can be referenced in code and runs in client
|
||||||
|
enable_starlight=0
|
||||||
|
enable_phosphor=0
|
||||||
|
enable_sodium=1
|
||||||
|
enable_lithium=0
|
||||||
|
enable_iris=0
|
||||||
|
enable_bclib=1
|
||||||
|
enable_canvas=0
|
||||||
|
|
||||||
|
# Forge loader
|
||||||
|
forge_version=43.1.1
|
||||||
|
# forge_version=43.1.34
|
||||||
|
# Forge mod versions
|
||||||
|
starlight_version_forge=0
|
||||||
|
terraforged_version=
|
||||||
|
|
||||||
|
# Forge mod run
|
||||||
|
# 0 = Don't enable and don't run
|
||||||
|
# 1 = Can be referenced in code but doesn't run
|
||||||
|
# 2 = Can be referenced in code and runs in client
|
||||||
|
enable_starlight_forge=0
|
||||||
|
enable_terraforged=0
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
# 1.18.2 version based stuff
|
||||||
|
|
||||||
|
java_version = 17
|
||||||
|
minecraft_version=1.19
|
||||||
|
parchment_version=2022.08.10
|
||||||
|
compatible_minecraft_versions=["1.19"]
|
||||||
|
|
||||||
|
# Fabric loader
|
||||||
|
fabric_loader_version=0.14.7
|
||||||
|
fabric_api_version=0.55.3+1.19
|
||||||
|
architectury_version=5.6.24
|
||||||
|
# Fabric mod versions
|
||||||
|
modmenu_version=4.0.0
|
||||||
|
starlight_version_fabric=
|
||||||
|
phosphor_version_fabric=
|
||||||
|
lithium_version=
|
||||||
|
sodium_version=3820973
|
||||||
|
iris_version=1.19.x-v1.2.5
|
||||||
|
immersive_portals_version =
|
||||||
|
bclib_version=
|
||||||
|
canvas_version=mc118:1.0.2397
|
||||||
|
|
||||||
|
# Fabric mod run
|
||||||
|
# 0 = Don't enable and don't run
|
||||||
|
# 1 = Can be referenced in code but doesn't run
|
||||||
|
# 2 = Can be referenced in code and runs in client
|
||||||
|
enable_starlight=0
|
||||||
|
enable_phosphor=0
|
||||||
|
enable_sodium=1
|
||||||
|
enable_lithium=0
|
||||||
|
enable_iris=0
|
||||||
|
enable_bclib=0
|
||||||
|
enable_canvas=0
|
||||||
|
|
||||||
|
# Forge loader
|
||||||
|
forge_version=41.0.19
|
||||||
|
# Forge mod versions
|
||||||
|
starlight_version_forge=0
|
||||||
|
terraforged_version=
|
||||||
|
|
||||||
|
# Forge mod run
|
||||||
|
# 0 = Don't enable and don't run
|
||||||
|
# 1 = Can be referenced in code but doesn't run
|
||||||
|
# 2 = Can be referenced in code and runs in client
|
||||||
|
enable_starlight_forge=0
|
||||||
|
enable_terraforged=0
|
||||||
@@ -0,0 +1,165 @@
|
|||||||
|
GNU LESSER GENERAL PUBLIC LICENSE
|
||||||
|
Version 3, 29 June 2007
|
||||||
|
|
||||||
|
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
|
||||||
|
This version of the GNU Lesser General Public License incorporates
|
||||||
|
the terms and conditions of version 3 of the GNU General Public
|
||||||
|
License, supplemented by the additional permissions listed below.
|
||||||
|
|
||||||
|
0. Additional Definitions.
|
||||||
|
|
||||||
|
As used herein, "this License" refers to version 3 of the GNU Lesser
|
||||||
|
General Public License, and the "GNU GPL" refers to version 3 of the GNU
|
||||||
|
General Public License.
|
||||||
|
|
||||||
|
"The Library" refers to a covered work governed by this License,
|
||||||
|
other than an Application or a Combined Work as defined below.
|
||||||
|
|
||||||
|
An "Application" is any work that makes use of an interface provided
|
||||||
|
by the Library, but which is not otherwise based on the Library.
|
||||||
|
Defining a subclass of a class defined by the Library is deemed a mode
|
||||||
|
of using an interface provided by the Library.
|
||||||
|
|
||||||
|
A "Combined Work" is a work produced by combining or linking an
|
||||||
|
Application with the Library. The particular version of the Library
|
||||||
|
with which the Combined Work was made is also called the "Linked
|
||||||
|
Version".
|
||||||
|
|
||||||
|
The "Minimal Corresponding Source" for a Combined Work means the
|
||||||
|
Corresponding Source for the Combined Work, excluding any source code
|
||||||
|
for portions of the Combined Work that, considered in isolation, are
|
||||||
|
based on the Application, and not on the Linked Version.
|
||||||
|
|
||||||
|
The "Corresponding Application Code" for a Combined Work means the
|
||||||
|
object code and/or source code for the Application, including any data
|
||||||
|
and utility programs needed for reproducing the Combined Work from the
|
||||||
|
Application, but excluding the System Libraries of the Combined Work.
|
||||||
|
|
||||||
|
1. Exception to Section 3 of the GNU GPL.
|
||||||
|
|
||||||
|
You may convey a covered work under sections 3 and 4 of this License
|
||||||
|
without being bound by section 3 of the GNU GPL.
|
||||||
|
|
||||||
|
2. Conveying Modified Versions.
|
||||||
|
|
||||||
|
If you modify a copy of the Library, and, in your modifications, a
|
||||||
|
facility refers to a function or data to be supplied by an Application
|
||||||
|
that uses the facility (other than as an argument passed when the
|
||||||
|
facility is invoked), then you may convey a copy of the modified
|
||||||
|
version:
|
||||||
|
|
||||||
|
a) under this License, provided that you make a good faith effort to
|
||||||
|
ensure that, in the event an Application does not supply the
|
||||||
|
function or data, the facility still operates, and performs
|
||||||
|
whatever part of its purpose remains meaningful, or
|
||||||
|
|
||||||
|
b) under the GNU GPL, with none of the additional permissions of
|
||||||
|
this License applicable to that copy.
|
||||||
|
|
||||||
|
3. Object Code Incorporating Material from Library Header Files.
|
||||||
|
|
||||||
|
The object code form of an Application may incorporate material from
|
||||||
|
a header file that is part of the Library. You may convey such object
|
||||||
|
code under terms of your choice, provided that, if the incorporated
|
||||||
|
material is not limited to numerical parameters, data structure
|
||||||
|
layouts and accessors, or small macros, inline functions and templates
|
||||||
|
(ten or fewer lines in length), you do both of the following:
|
||||||
|
|
||||||
|
a) Give prominent notice with each copy of the object code that the
|
||||||
|
Library is used in it and that the Library and its use are
|
||||||
|
covered by this License.
|
||||||
|
|
||||||
|
b) Accompany the object code with a copy of the GNU GPL and this license
|
||||||
|
document.
|
||||||
|
|
||||||
|
4. Combined Works.
|
||||||
|
|
||||||
|
You may convey a Combined Work under terms of your choice that,
|
||||||
|
taken together, effectively do not restrict modification of the
|
||||||
|
portions of the Library contained in the Combined Work and reverse
|
||||||
|
engineering for debugging such modifications, if you also do each of
|
||||||
|
the following:
|
||||||
|
|
||||||
|
a) Give prominent notice with each copy of the Combined Work that
|
||||||
|
the Library is used in it and that the Library and its use are
|
||||||
|
covered by this License.
|
||||||
|
|
||||||
|
b) Accompany the Combined Work with a copy of the GNU GPL and this license
|
||||||
|
document.
|
||||||
|
|
||||||
|
c) For a Combined Work that displays copyright notices during
|
||||||
|
execution, include the copyright notice for the Library among
|
||||||
|
these notices, as well as a reference directing the user to the
|
||||||
|
copies of the GNU GPL and this license document.
|
||||||
|
|
||||||
|
d) Do one of the following:
|
||||||
|
|
||||||
|
0) Convey the Minimal Corresponding Source under the terms of this
|
||||||
|
License, and the Corresponding Application Code in a form
|
||||||
|
suitable for, and under terms that permit, the user to
|
||||||
|
recombine or relink the Application with a modified version of
|
||||||
|
the Linked Version to produce a modified Combined Work, in the
|
||||||
|
manner specified by section 6 of the GNU GPL for conveying
|
||||||
|
Corresponding Source.
|
||||||
|
|
||||||
|
1) Use a suitable shared library mechanism for linking with the
|
||||||
|
Library. A suitable mechanism is one that (a) uses at run time
|
||||||
|
a copy of the Library already present on the user's computer
|
||||||
|
system, and (b) will operate properly with a modified version
|
||||||
|
of the Library that is interface-compatible with the Linked
|
||||||
|
Version.
|
||||||
|
|
||||||
|
e) Provide Installation Information, but only if you would otherwise
|
||||||
|
be required to provide such information under section 6 of the
|
||||||
|
GNU GPL, and only to the extent that such information is
|
||||||
|
necessary to install and execute a modified version of the
|
||||||
|
Combined Work produced by recombining or relinking the
|
||||||
|
Application with a modified version of the Linked Version. (If
|
||||||
|
you use option 4d0, the Installation Information must accompany
|
||||||
|
the Minimal Corresponding Source and Corresponding Application
|
||||||
|
Code. If you use option 4d1, you must provide the Installation
|
||||||
|
Information in the manner specified by section 6 of the GNU GPL
|
||||||
|
for conveying Corresponding Source.)
|
||||||
|
|
||||||
|
5. Combined Libraries.
|
||||||
|
|
||||||
|
You may place library facilities that are a work based on the
|
||||||
|
Library side by side in a single library together with other library
|
||||||
|
facilities that are not Applications and are not covered by this
|
||||||
|
License, and convey such a combined library under terms of your
|
||||||
|
choice, if you do both of the following:
|
||||||
|
|
||||||
|
a) Accompany the combined library with a copy of the same work based
|
||||||
|
on the Library, uncombined with any other library facilities,
|
||||||
|
conveyed under the terms of this License.
|
||||||
|
|
||||||
|
b) Give prominent notice with the combined library that part of it
|
||||||
|
is a work based on the Library, and explaining where to find the
|
||||||
|
accompanying uncombined form of the same work.
|
||||||
|
|
||||||
|
6. Revised Versions of the GNU Lesser General Public License.
|
||||||
|
|
||||||
|
The Free Software Foundation may publish revised and/or new versions
|
||||||
|
of the GNU Lesser General Public License from time to time. Such new
|
||||||
|
versions will be similar in spirit to the present version, but may
|
||||||
|
differ in detail to address new problems or concerns.
|
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the
|
||||||
|
Library as you received it specifies that a certain numbered version
|
||||||
|
of the GNU Lesser General Public License "or any later version"
|
||||||
|
applies to it, you have the option of following the terms and
|
||||||
|
conditions either of that published version or of any later version
|
||||||
|
published by the Free Software Foundation. If the Library as you
|
||||||
|
received it does not specify a version number of the GNU Lesser
|
||||||
|
General Public License, you may choose any version of the GNU Lesser
|
||||||
|
General Public License ever published by the Free Software Foundation.
|
||||||
|
|
||||||
|
If the Library as you received it specifies that a proxy can decide
|
||||||
|
whether future versions of the GNU Lesser General Public License shall
|
||||||
|
apply, that proxy's public statement of acceptance of any version is
|
||||||
|
permanent authorization for you to choose that version for the
|
||||||
|
Library.
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
# <img src="https://gitlab.com/jeseibel/distant-horizons-core/-/raw/main/_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
|
||||||
|
|
||||||
> A mod that adds a Level of Detail System to Minecraft
|
> A mod that adds a Level of Detail System to Minecraft
|
||||||
|
|
||||||
@@ -9,84 +9,109 @@ This mod adds a Level Of Detail (LOD) system to Minecraft.\
|
|||||||
This implementation renders simplified chunks outside the normal render distance\
|
This implementation renders simplified chunks outside the normal render distance\
|
||||||
allowing for an increased view distance without harming performance.
|
allowing for an increased view distance without harming performance.
|
||||||
|
|
||||||
Or in other words: this mod lets you see farther without turning your game into a slide show.\
|
In other words: this mod lets you see farther without turning your game into a slide show.\
|
||||||
If you want to see a quick demo, check out a video covering the mod here:
|
If you want to see a quick demo, check out a video covering the mod here:
|
||||||
|
|
||||||
<a href="https://www.youtube.com/watch?v=H2tnvEVbO1c" target="_blank"></a>
|
<a href="https://youtu.be/_04BZ8W2bDM" target="_blank"></a>
|
||||||
|
|
||||||
### Versions
|
<br>
|
||||||
|
|
||||||
Architectury version: 3.4-SNAPSHOT\
|
## Mod and Library Versions
|
||||||
Java Compiler plugin: Manifold Preprocessor
|
|
||||||
|
|
||||||
#### 1.18.2 mods
|
This branch supports the following versions of Minecraft:
|
||||||
|
|
||||||
|
#### 1.19 (WIP)
|
||||||
|
Supported MC versions: [1.19]\
|
||||||
|
Forge version: 41.0.19\
|
||||||
|
Fabric version: 0.14.7\
|
||||||
|
Fabric API version: 0.55.3+1.19\
|
||||||
|
Modmenu version: 4.0.0
|
||||||
|
|
||||||
|
#### 1.18.2
|
||||||
|
Supported MC versions: [1.18.2]\
|
||||||
Forge version: 40.0.18\
|
Forge version: 40.0.18\
|
||||||
Fabric version: 0.13.3\
|
Fabric version: 0.13.3\
|
||||||
Fabric API version: 0.48.0+1.18.2\
|
Fabric API version: 0.48.0+1.18.2\
|
||||||
Modmenu version: 3.1.0
|
Modmenu version: 3.1.0
|
||||||
|
|
||||||
#### 1.18.1 mods
|
#### 1.18.1
|
||||||
|
Supported MC versions: [1.18.1, 1.18]\
|
||||||
Forge version: 39.1.2\
|
Forge version: 39.1.2\
|
||||||
Fabric version: 0.13.3\
|
Fabric version: 0.13.3\
|
||||||
Fabric API version: 0.46.6+1.18\
|
Fabric API version: 0.42.6+1.18\
|
||||||
Modmenu version: 3.0.1
|
Modmenu version: 3.0.1
|
||||||
|
|
||||||
|
#### 1.17.1
|
||||||
|
Supported MC versions: [1.17.1, 1.17]\
|
||||||
|
Forge version: 37.1.1\
|
||||||
|
Fabric version: 0.13.2\
|
||||||
|
Fabric API version: 0.46.1+1.17\
|
||||||
|
Modmenu version: 2.0.14
|
||||||
|
|
||||||
Notes:\
|
#### 1.16.5
|
||||||
This version has been confirmed to work in IDE and Retail Minecraft.\
|
Supported MC versions: [1.16.5, 1.16.4]\
|
||||||
(Retail running forge version 1.18.1-39.0.5 and fabric version 1.18-0.12.12 and 1.18.1-0.13.2)
|
Forge version: 36.2.28\
|
||||||
|
Fabric vetsion: 0.13.2\
|
||||||
|
Fabric API version: 0.42.0+1.16\
|
||||||
|
Modmenu version: 1.16.22
|
||||||
|
<br><br>
|
||||||
|
|
||||||
|
#### Plugin and Library versions
|
||||||
|
|
||||||
|
Architectury version: 3.4-SNAPSHOT\
|
||||||
|
Architectury loom version: 0.12.0-SNAPSHOT\
|
||||||
|
Java Compiler plugin: Manifold Preprocessor
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
## Source Code Installation
|
## Source Code Installation
|
||||||
|
|
||||||
See the Fabric Documentation online for more detailed instructions:\
|
|
||||||
https://fabricmc.net/wiki/tutorial:setup
|
|
||||||
|
|
||||||
### Prerequisites
|
### Prerequisites
|
||||||
|
|
||||||
* A Java Development Kit (JDK) for Java 17 (recommended) or newer. Visit https://www.oracle.com/java/technologies/downloads/ for installers.
|
* A Java Development Kit (JDK) for Java 17 (recommended) or newer. <br>
|
||||||
* Git or someway to clone git projects. Visit https://git-scm.com/ for installers.
|
Visit https://www.oracle.com/java/technologies/downloads/ for installers.
|
||||||
|
* Git or someway to clone git projects. <br>
|
||||||
|
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:**
|
||||||
0. Install Manifold plugin
|
1. Install the Manifold plugin
|
||||||
1. open IDEA and import the build.gradle
|
2. Open IDEA and import the build.gradle
|
||||||
2. refresh the Gradle project in IDEA if required
|
3. Refresh the Gradle project in IDEA if required
|
||||||
|
|
||||||
**If using Ecplise: (Note that Eclispe currently doesn't support Manifold's preprocessor!)**
|
**If using Eclipse: (Note that Eclipse doesn't support Manifold's preprocessor!)**
|
||||||
1. run the command: `./gradlew geneclipseruns`
|
1. Run the command: `./gradlew geneclipseruns`
|
||||||
2. run the command: `./gradlew eclipse`
|
2. Run the command: `./gradlew eclipse`
|
||||||
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
|
||||||
|
|
||||||
## Switching Versions
|
## Switching Versions
|
||||||
This branch support 2 built versions:
|
|
||||||
- 1.18.2
|
|
||||||
- 1.18.1 (which also runs on 1.18)
|
|
||||||
|
|
||||||
To switch between active versions, change `mcVer=1.18.?` in `gradle.properties` file.
|
To switch between active versions, change `mcVer=1.?` in `gradle.properties` file.
|
||||||
|
|
||||||
If running on IDE, to ensure IDE pickup the changed versions, you will need to run a gradle command again to allow gradle to update all the libs. (In IntellJ you will also need to do a gradle sync again if it didn't start it automatically.)
|
If running in an IDE, to ensure the IDE noticed the version change, run a gradle command to prompt gradle into updating the libs. (In IntellJ you will also need to do a gradle sync if it didn't happen automatically.)
|
||||||
>Note: There may be a `java.nio.file.FileSystemException` thrown on running the command after switching versions. To fix it, either restart your IDE (as your IDE is locking up a file) or use tools like LockHunter to unlock the linked file. (Often a lib file under `common\build\lib` or `forge\build\lib` or `fabric\build\lib`). If anyone knows how to solve this issue please comment to this issue: https://gitlab.com/jeseibel/minecraft-lod-mod/-/issues/233
|
>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 locking up a file) or use a tool like LockHunter to unlock the linked file(s). (Generally it is a lib file under `common\build\lib`, `forge\build\lib`, or `fabric\build\lib`). If anyone knows how to solve this issue please write a comment on this issue: https://gitlab.com/jeseibel/minecraft-lod-mod/-/issues/233
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
## Compiling
|
## Compiling
|
||||||
|
|
||||||
**Using GUI**
|
**From the File Explorer:**
|
||||||
1. Download the zip of the project and extract it
|
1. Download and extract the zip of the project
|
||||||
2. Download the core from https://gitlab.com/jeseibel/distant-horizons-core and extract into a folder called `core`
|
2. Download the core from https://gitlab.com/jeseibel/distant-horizons-core and extract into a folder called `core`
|
||||||
3. Open a command line in the project folder
|
3. Open a terminal emulator in the project folder (On Windows you can type `cmd` in the title bar)
|
||||||
4. Run the command: `./gradlew assemble`
|
4. Run the commands: `./gradlew assemble`
|
||||||
5. Then run command: `./gradlew mergeJars`
|
|
||||||
6. The compiled jar file will be in the folder `Merged`
|
6. The compiled jar file will be in the folder `Merged`
|
||||||
|
|
||||||
**If in terminal:**
|
**If in terminal:**
|
||||||
1. `git clone -b preprocessor_test --recurse-submodules https://gitlab.com/jeseibel/minecraft-lod-mod.git`
|
1. `git clone --recurse-submodules https://gitlab.com/jeseibel/minecraft-lod-mod.git`
|
||||||
2. `cd minecraft-lod-mod`
|
2. `cd minecraft-lod-mod`
|
||||||
3. `./gradlew assemble`
|
3. `./gradlew assemble`
|
||||||
4. `./gradlew mergeJars`
|
4. The compiled jar file will be in the folder `Merged`
|
||||||
5. The compiled jar file will be in the folder `Merged`
|
|
||||||
>Note: You can add the arg: `-PmcVer=1.18.?` to tell gradle to build a selected MC version instead of having to manually modify the `gradle.properties` file.
|
|
||||||
|
|
||||||
|
>Note: You can add the arg: `-PmcVer=1.?` to tell gradle to build a selected MC version instead of having to manually modify the `gradle.properties` file.
|
||||||
|
|
||||||
|
<Br>
|
||||||
|
|
||||||
## Other commands
|
## Other commands
|
||||||
|
|
||||||
@@ -99,19 +124,40 @@ If running on IDE, to ensure IDE pickup the changed versions, you will need to r
|
|||||||
|
|
||||||
The Minecraft source code is NOT added to your workspace in an editable way. Minecraft is treated like a normal Library. Sources are there for documentation and research purposes only.
|
The Minecraft source code is NOT added to your workspace in an editable way. Minecraft is treated like a normal Library. Sources are there for documentation and research purposes only.
|
||||||
|
|
||||||
Source code uses Mojang mappings.
|
Source code uses Mojang mappings & [Parchment](https://parchmentmc.org/) mappings.
|
||||||
|
|
||||||
|
To generate the source code run `./gradlew genSources`\
|
||||||
|
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)
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
## Useful commands
|
## Useful commands
|
||||||
|
|
||||||
Build only Fabric: `./gradlew fabric:assemble` or `./gradlew fabric:build`\
|
Run the standalone jar: `./gradlew run`\
|
||||||
Build only Forge: `./gradlew fabric:assemble` or `./gradlew forge:build`\
|
Build the standalone jar: `./gradlew core:build`\
|
||||||
|
Only build Fabric: `./gradlew fabric:assemble` or `./gradlew fabric:build`\
|
||||||
|
Only build Forge: `./gradlew fabric:assemble` or `./gradlew forge:build`\
|
||||||
Run the Fabric client (for debugging): `./gradlew fabric:runClient`\
|
Run the Fabric client (for debugging): `./gradlew fabric:runClient`\
|
||||||
Run the Forge client (for debugging): `./gradlew forge:runClient`
|
Run the Forge client (for debugging): `./gradlew forge:runClient`
|
||||||
|
|
||||||
|
To build all versions: `./buildAll` (all builds will end up in the `Merged` folder)
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
## Open Source Acknowledgements
|
## Open Source Acknowledgements
|
||||||
|
|
||||||
XZ for Java (data compression)\
|
XZ for Java (data compression)\
|
||||||
https://tukaani.org/xz/java.html
|
https://tukaani.org/xz/java.html
|
||||||
|
|
||||||
DHJarMerger (To merge multiple mod versions into one jar)\
|
Forgix (To merge multiple mod versions into one jar) [_Used to be_ [_DHJarMerger_](https://github.com/Ran-helo/DHJarMerger)]\
|
||||||
https://github.com/Ran-helo/DHJarMerger
|
https://github.com/PacifistMC/Forgix
|
||||||
|
|
||||||
|
Json & Toml for Java (config handling)\
|
||||||
|
https://github.com/TheElectronWill/night-config
|
||||||
|
|
||||||
|
SVG Salamander for SVG's\
|
||||||
|
https://github.com/blackears/svgSalamander
|
||||||
|
|
||||||
|
FlatLaf for theming (Tempory to test stuff)\
|
||||||
|
https://www.formdev.com/flatlaf/
|
||||||
|
|||||||
+328
-67
@@ -1,91 +1,295 @@
|
|||||||
import io.github.ran.jarmerger.JarMergerPlugin
|
|
||||||
|
|
||||||
|
|
||||||
buildscript {
|
|
||||||
dependencies{
|
|
||||||
classpath files('plugins/DHJarMerger-1.0.jar')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
|
// Plugin to help in developing multi-loader mods
|
||||||
id "architectury-plugin" version "3.4-SNAPSHOT"
|
id "architectury-plugin" version "3.4-SNAPSHOT"
|
||||||
id "dev.architectury.loom" version "0.10.0-SNAPSHOT" apply false
|
id "dev.architectury.loom" version "0.12.0-SNAPSHOT" apply false
|
||||||
|
|
||||||
|
// Plugin to handle dependencies
|
||||||
|
id 'com.github.johnrengelman.shadow' version '7.0.0' apply false
|
||||||
|
|
||||||
|
// Plugin to create merged jars
|
||||||
|
id "io.github.pacifistmc.forgix" version "1.2.6"
|
||||||
|
|
||||||
|
// Provides mc libraries to core
|
||||||
|
id 'org.spongepowered.gradle.vanilla' version '0.2.1-SNAPSHOT' apply false
|
||||||
}
|
}
|
||||||
|
|
||||||
def writeBuildGradlePredefine() {
|
/**
|
||||||
def excapedMCVersion = rootProject.minecraft_version.replace(".", "_")
|
* Creates the list of preprocessors to use.
|
||||||
new File(projectDir, "build.properties").text = "MC_VERSION_${excapedMCVersion}=\n"
|
*
|
||||||
}
|
* @param mcVers array of all MC versions
|
||||||
|
* @param mcIndex array index of the currently active MC version
|
||||||
|
*/
|
||||||
|
def writeBuildGradlePredefine(List<String> mcVers, int mcIndex) {
|
||||||
|
|
||||||
def loadProperties() {
|
ArrayList<String> redefineList = new ArrayList<String>()
|
||||||
def defaultMcVersion = '1.18.2'
|
for (int i=0; i<mcVers.size(); i++) {
|
||||||
if (!project.hasProperty("mcVer")) {
|
String mcStr = mcVers.get(i).replace(".", "_")
|
||||||
println "No mcVer set! Defaulting to ${defaultMcVersion}."
|
if (mcIndex<i) {
|
||||||
println "Tip: Use -PmcVer='${defaultMcVersion}' in cmd arg to set mcVer."
|
redefineList.add("PRE_MC_"+mcStr)
|
||||||
|
}
|
||||||
|
if (mcIndex==i) {
|
||||||
|
redefineList.add("MC_"+mcStr)
|
||||||
|
}
|
||||||
|
if (mcIndex>=i) {
|
||||||
|
redefineList.add("POST_MC_"+mcStr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// build the list of preprocessors to use
|
||||||
|
StringBuilder sb = new StringBuilder()
|
||||||
|
|
||||||
|
// check if this is a development build
|
||||||
|
if (mod_version.toLowerCase().contains("dev")) {
|
||||||
|
// WARNING: only use this for logging, we don't want to have confusion
|
||||||
|
// when a method doesn't work correctly in the release build.
|
||||||
|
sb.append("DEV_BUILD")
|
||||||
|
sb.append("=\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
// build the MC version preprocessors
|
||||||
|
for (String redefinedVersion : redefineList) {
|
||||||
|
sb.append(redefinedVersion)
|
||||||
|
sb.append("=\n")
|
||||||
|
}
|
||||||
|
new File(projectDir, "build.properties").text = sb.toString()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sets up the variables for Manifold in the code
|
||||||
|
def loadProperties() {
|
||||||
|
def defaultMcVersion = "1.19.2"
|
||||||
|
// def defaultMcVersion = "1.19" // For now use 1.18.2 as default until 1.19 is done
|
||||||
|
def mcVersion = ""
|
||||||
|
def mcVers = mcVersions.split(",")
|
||||||
|
int mcIndex = -1
|
||||||
|
println "Avalible MC versions: ${mcVersions}"
|
||||||
|
if (project.hasProperty("mcVer")) {
|
||||||
|
mcVersion = mcVer
|
||||||
|
mcIndex = Arrays.asList(mcVers).indexOf(mcVer)
|
||||||
|
}
|
||||||
|
if (mcIndex == -1) {
|
||||||
|
println "No mcVer set or the set mcVer is invalid! Defaulting to ${defaultMcVersion}."
|
||||||
|
println "Tip: Use -PmcVer='${defaultMcVersion}' in cmd arg to set mcVer."
|
||||||
|
mcVersion = defaultMcVersion
|
||||||
|
mcIndex = Arrays.asList(mcVers).indexOf(defaultMcVersion)
|
||||||
|
assert mcIndex != -1
|
||||||
}
|
}
|
||||||
def mcVersion = project.hasProperty("mcVer") ? mcVer : defaultMcVersion
|
|
||||||
|
|
||||||
println "Loading properties file at " + mcVersion + ".properties"
|
println "Loading properties file at " + mcVersion + ".properties"
|
||||||
def props = new Properties()
|
def props = new Properties()
|
||||||
props.load(new FileInputStream("$rootProject.rootDir/"+"$mcVersion"+".properties"))
|
props.load(new FileInputStream("$rootProject.rootDir/"+"$mcVersion"+".properties"))
|
||||||
|
|
||||||
props.each { prop ->
|
props.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 + "]"
|
||||||
}
|
}
|
||||||
writeBuildGradlePredefine()
|
writeBuildGradlePredefine(Arrays.asList(mcVers), mcIndex)
|
||||||
|
|
||||||
|
// Stuff for access wideners
|
||||||
|
def mcVersionToAcsessWidenerVersion = [
|
||||||
|
"1.16.5": "1_16",
|
||||||
|
"1.17.1": "1_17",
|
||||||
|
"1.18.1": "1_18",
|
||||||
|
"1.18.2": "1_18",
|
||||||
|
"1.19": "1_19",
|
||||||
|
"1.19.1": "1_19",
|
||||||
|
"1.19.2": "1_19"
|
||||||
|
]
|
||||||
|
// Use this as sometimes multiple versions use the same access wideners
|
||||||
|
rootProject.ext.set("accessWidenerVersion", mcVersionToAcsessWidenerVersion.get(mcVersion))
|
||||||
}
|
}
|
||||||
loadProperties()
|
loadProperties()
|
||||||
|
|
||||||
apply plugin: JarMergerPlugin
|
// Sets up the accesswideners
|
||||||
|
def makeAccessWidener() {
|
||||||
|
def accessWidenerFile = project(":common").file("src/main/resources/lod.accesswidener")
|
||||||
|
if (accessWidenerFile.exists()) {
|
||||||
|
delete accessWidenerFile
|
||||||
|
}
|
||||||
|
|
||||||
|
copy {
|
||||||
|
from project(":common").file("src/main/resources/${rootProject.accessWidenerVersion}.lod.accesswidener")
|
||||||
|
into project(":common").file("src/main/resources/")
|
||||||
|
rename "${rootProject.accessWidenerVersion}.lod.accesswidener", "lod.accesswidener"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
makeAccessWidener()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Sets up the version string
|
||||||
|
rootProject.versionStr = rootProject.mod_version + "-" + rootProject.minecraft_version // + "-" + new Date().format("yyyy_MM_dd_HH_mm")
|
||||||
|
|
||||||
|
// Merged jar settings
|
||||||
|
forgix {
|
||||||
|
group = "com.seibel.lod"
|
||||||
|
mergedJarName = "DistantHorizons-${rootProject.versionStr}.jar"
|
||||||
|
|
||||||
|
forge {
|
||||||
|
jarLocation = "build/libs/DistantHorizons-${rootProject.versionStr}.jar"
|
||||||
|
}
|
||||||
|
|
||||||
|
fabric {
|
||||||
|
jarLocation = "build/libs/DistantHorizons-${rootProject.versionStr}.jar"
|
||||||
|
}
|
||||||
|
|
||||||
|
removeDuplicate "com.seibel.lod.api"
|
||||||
|
removeDuplicate "com.seibel.lod.core"
|
||||||
|
}
|
||||||
|
|
||||||
architectury {
|
architectury {
|
||||||
minecraft = rootProject.minecraft_version
|
minecraft = rootProject.minecraft_version
|
||||||
}
|
}
|
||||||
|
|
||||||
subprojects { p ->
|
subprojects { p ->
|
||||||
apply plugin: "dev.architectury.loom"
|
|
||||||
|
// setup Architectury
|
||||||
loom {
|
if (p == project(":core") || p == project(":api")) {
|
||||||
silentMojangMappingsLicense()
|
apply plugin: "application"
|
||||||
|
apply plugin: "org.spongepowered.gradle.vanilla" // Provides minecraft libraries
|
||||||
|
apply plugin: "com.github.johnrengelman.shadow"
|
||||||
|
} else {
|
||||||
|
apply plugin: "com.github.johnrengelman.shadow"
|
||||||
|
apply plugin: "dev.architectury.loom"
|
||||||
|
|
||||||
|
loom {
|
||||||
|
silentMojangMappingsLicense()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// set up custom configurations (configurations are a way to handle dependencies)
|
||||||
configurations {
|
configurations {
|
||||||
common
|
// extends the shadowJar configuration
|
||||||
shadowMe
|
shadowMe
|
||||||
implementation.extendsFrom shadowMe
|
// have implemented dependencies automatically embedded in the final jar
|
||||||
|
implementation.extendsFrom(shadowMe)
|
||||||
|
|
||||||
|
customModule
|
||||||
|
implementation.extendsFrom(customModule)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set up the minecraft non-dependency for core sub-projects
|
||||||
|
if (p == project(":core") || p == project(":api")) {
|
||||||
|
minecraft {
|
||||||
|
version("${rootProject.minecraft_version}")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the standalone jar entrypoint
|
||||||
|
// (This will point to a non-existent class in all sub-projects except "Core")
|
||||||
|
application {
|
||||||
|
mainClass.set('com.seibel.lod.core.jar.JarMain')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
minecraft "com.mojang:minecraft:${rootProject.minecraft_version}"
|
|
||||||
// The following line declares the mojmap mappings
|
//=====================//
|
||||||
mappings loom.officialMojangMappings()
|
// shared dependencies //
|
||||||
|
//=====================//
|
||||||
//Manifold
|
|
||||||
annotationProcessor "systems.manifold:manifold-preprocessor:${rootProject.manifold_version}"
|
|
||||||
|
|
||||||
// Toml
|
// Manifold
|
||||||
implementation("com.electronwill.night-config:toml:${rootProject.toml_version}")
|
annotationProcessor("systems.manifold:manifold-preprocessor:${rootProject.manifold_version}")
|
||||||
|
|
||||||
if (p != project(":forge")) {
|
// JUnit tests
|
||||||
// We depend on fabric loader here to use the fabric @Environment annotations and get the mixin dependencies
|
implementation("org.junit.jupiter:junit-jupiter:5.8.2")
|
||||||
// Do NOT use other classes from fabric loader unless working with fabric
|
implementation("org.junit.jupiter:junit-jupiter-engine:5.8.2")
|
||||||
modImplementation "net.fabricmc:fabric-loader:${rootProject.fabric_loader_version}"
|
implementation("junit:junit:4.13")
|
||||||
|
|
||||||
|
// Compression
|
||||||
|
shadowMe("org.tukaani:xz:1.9")
|
||||||
|
shadowMe("org.apache.commons:commons-compress:1.21")
|
||||||
|
|
||||||
|
// NightConfig (includes Toml & Json)
|
||||||
|
shadowMe("com.electronwill.night-config:toml:${rootProject.nightconfig_version}")
|
||||||
|
shadowMe("com.electronwill.night-config:json:${rootProject.nightconfig_version}")
|
||||||
|
|
||||||
|
// Theming
|
||||||
|
shadowMe("com.formdev:flatlaf:${rootProject.flatlaf_version}")
|
||||||
|
|
||||||
|
// SVG
|
||||||
|
shadowMe("com.formdev:flatlaf-extras:${rootProject.flatlaf_version}")
|
||||||
|
shadowMe("com.formdev:svgSalamander:${rootProject.svgSalamander_version}")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//==========================//
|
||||||
|
// conditional dependencies //
|
||||||
|
//==========================//
|
||||||
|
|
||||||
|
// The logic for buildForge can be made more succinct, but the readability goes way down.
|
||||||
|
def buildForge = true
|
||||||
|
if (gradle.startParameter.taskRequests.size() > 0) {
|
||||||
|
if (gradle.startParameter.taskRequests[0].args.size() > 0) {
|
||||||
|
if (gradle.startParameter.taskRequests[0].args[0].startsWith("fabric:")) {
|
||||||
|
buildForge = false
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p != project(":core")) {
|
// Minecraft dependent sub-projects
|
||||||
common(project(":core")) { transitive false }
|
if (p == project(":common") || (buildForge && p == project(":forge")) || p == project(":fabric")) {
|
||||||
shadowMe(project(":core")) { transitive false }
|
// Add Minecraft
|
||||||
|
minecraft "com.mojang:minecraft:${rootProject.minecraft_version}"
|
||||||
|
// The following line declares the mojmap mappings & parchment mappings
|
||||||
|
mappings loom.layered() {
|
||||||
|
// Mojmap mappings
|
||||||
|
officialMojangMappings()
|
||||||
|
// Parchment mappings (it adds parameter mappings & javadoc)
|
||||||
|
parchment("org.parchmentmc.data:parchment-${rootProject.minecraft_version}:${rootProject.parchment_version}@zip")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add core
|
||||||
|
if (p != project(":api") && p != project(":core")) {
|
||||||
|
implementation(project(":core")) {
|
||||||
|
// Remove Junit test libraries
|
||||||
|
exclude group: "org.junit.jupiter", module: "junit-jupiter"
|
||||||
|
exclude group: "org.junit.jupiter", module: "junit-jupiter-engine"
|
||||||
|
exclude group: "junit", module: "junit"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add the api
|
||||||
|
if (p != project(":api")) {
|
||||||
|
implementation(project(":api")) {
|
||||||
|
// Remove Junit test libraries
|
||||||
|
exclude group: "org.junit.jupiter", module: "junit-jupiter"
|
||||||
|
exclude group: "org.junit.jupiter", module: "junit-jupiter-engine"
|
||||||
|
exclude group: "junit", module: "junit"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Allows the jar to run standalone
|
||||||
jar {
|
jar {
|
||||||
manifest {
|
manifest {
|
||||||
attributes 'Implementation-Title': rootProject.archives_base_name,
|
attributes 'Implementation-Title': rootProject.archives_base_name,
|
||||||
'Implementation-Version': rootProject.mod_version,
|
'Implementation-Version': rootProject.mod_version,
|
||||||
'Main-Class': 'com.seibel.lod.core.JarMain'
|
'Main-Class': 'com.seibel.lod.core.jar.JarMain' // When changing the main of the jar change this line
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// this can be un-commented if we ever wanted to make DH modular (AKA use a module-info.java file) again
|
||||||
|
// // Tells gradle where to look for other modules
|
||||||
|
// // Why isn't the classpath added to the modules path by default?
|
||||||
|
// if (p == project(":core")) {
|
||||||
|
// compileJava {
|
||||||
|
// inputs.property('moduleName', 'dhApi')
|
||||||
|
// doFirst {
|
||||||
|
// options.compilerArgs = [
|
||||||
|
// '--module-path', classpath.asPath
|
||||||
|
// ]
|
||||||
|
// classpath = files()
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// Run mergeJars when running build
|
||||||
|
if (p != project(":api") && p != project(":api")) {
|
||||||
|
build.finalizedBy(mergeJars)
|
||||||
|
assemble.finalizedBy(mergeJars)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
allprojects { p ->
|
allprojects { p ->
|
||||||
@@ -99,11 +303,18 @@ allprojects { p ->
|
|||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
|
|
||||||
|
// For parchment mappings
|
||||||
|
maven { url "https://maven.parchmentmc.org" }
|
||||||
|
|
||||||
|
// For Architectury API
|
||||||
|
maven { url "https://maven.architectury.dev" }
|
||||||
|
|
||||||
// used to download and compile dependencies from git repos
|
// used to download and compile dependencies from git repos
|
||||||
maven { url 'https://jitpack.io' }
|
maven { url 'https://jitpack.io' }
|
||||||
|
|
||||||
// For Manifold Preprocessor
|
// For Manifold Preprocessor
|
||||||
maven { url 'https://oss.sonatype.org/content/repositories/snapshots/' }
|
maven { url 'https://oss.sonatype.org/content/repositories/snapshots/' }
|
||||||
|
|
||||||
// Required for importing Modrinth mods
|
// Required for importing Modrinth mods
|
||||||
maven {
|
maven {
|
||||||
@@ -122,6 +333,15 @@ allprojects { p ->
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Required for ModMenu
|
||||||
|
maven { url "https://maven.terraformersmc.com/" }
|
||||||
|
|
||||||
|
// Required for Mixins & VanillaGradle
|
||||||
|
maven { url "https://repo.spongepowered.org/maven/" }
|
||||||
|
|
||||||
|
// Required for canvas
|
||||||
|
maven { url "https://maven.vram.io/" }
|
||||||
|
|
||||||
// These 2 are for importing mods that arnt on CursedForge, Modrinth, GitHub, GitLab or anywhere opensource
|
// These 2 are for importing mods that arnt on CursedForge, Modrinth, GitHub, GitLab or anywhere opensource
|
||||||
flatDir {
|
flatDir {
|
||||||
dirs "${rootDir}/mods/fabric"
|
dirs "${rootDir}/mods/fabric"
|
||||||
@@ -138,22 +358,49 @@ allprojects { p ->
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Only uncomment this when testing stuff with lwjgl in the core jar
|
||||||
|
// if (p == project(":core")) {
|
||||||
|
// dependencies {
|
||||||
|
// project.ext.lwjglNatives = "natives-linux"
|
||||||
|
//
|
||||||
|
// implementation platform("org.lwjgl:lwjgl-bom:3.3.0")
|
||||||
|
//
|
||||||
|
// 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:1.10.2"
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
// Put stuff from gradle.properties into the mod info
|
// Put stuff from gradle.properties into the mod info
|
||||||
processResources {
|
processResources {
|
||||||
def resourceTargets = ["fabric.mod.json", "META-INF/mods.toml"] // Location of where to put
|
def resourceTargets = ["fabric.mod.json", "META-INF/mods.toml"] // Location of where to put
|
||||||
def intoTargets = ["$buildDir/resources/main/"] // Location of the built resources folder
|
def intoTargets = ["$buildDir/resources/main/"] // Location of the built resources folder
|
||||||
def replaceProperties = [
|
def replaceProperties = [
|
||||||
version: mod_version,
|
version : mod_version,
|
||||||
mod_name: mod_name,
|
mod_name : mod_name,
|
||||||
authors: mod_authors,
|
authors : mod_authors,
|
||||||
description: mod_description,
|
description : mod_description,
|
||||||
homepage: mod_homepage,
|
homepage : mod_homepage,
|
||||||
source: mod_source,
|
source : mod_source,
|
||||||
issues: mod_issues,
|
issues : mod_issues,
|
||||||
minecraft_version: minecraft_version,
|
minecraft_version : minecraft_version,
|
||||||
java_version: java_version
|
compatible_minecraft_versions: compatible_minecraft_versions,
|
||||||
] // 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
|
java_version : java_version
|
||||||
//TODO: Make Forge loader version also be relaced with non hardcoded value instead of "[36,41)"
|
]
|
||||||
|
// 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
|
||||||
|
//TODO: Make Forge loader version also be relaced with non hardcoded value instead of "[36,42)"
|
||||||
|
|
||||||
inputs.properties replaceProperties
|
inputs.properties replaceProperties
|
||||||
replaceProperties.put 'project', project
|
replaceProperties.put 'project', project
|
||||||
@@ -174,26 +421,40 @@ allprojects { p ->
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
task copyCoreResources(type: Copy) {
|
||||||
|
from fileTree(project(":core").file("src/main/resources"))
|
||||||
|
into p.file("build/resources/main")
|
||||||
|
}
|
||||||
|
|
||||||
tasks.withType(JavaCompile) {
|
tasks.withType(JavaCompile) {
|
||||||
// Add Manifold Preprocessor
|
|
||||||
// def excapedMCVersion = rootProject.minecraft_version.replace(".", "_")
|
|
||||||
// options.compilerArgs += ['-Xplugin:Manifold', "-AMC_VERSION_${excapedMCVersion}"]
|
|
||||||
//
|
|
||||||
options.compilerArgs += ['-Xplugin:Manifold']
|
|
||||||
|
|
||||||
// println options.compilerArgs
|
|
||||||
if (p != project(":core")) {
|
if (p != project(":core")) {
|
||||||
options.release = rootProject.java_version as Integer
|
options.release = rootProject.java_version as Integer
|
||||||
|
options.compilerArgs += ['-Xplugin:Manifold']
|
||||||
|
} else {
|
||||||
|
// options.release = 8; // Core should use Java 8 no matter what
|
||||||
|
// No it shouldn't cause it fails to find minecraft if it uses Java 8
|
||||||
|
options.release = rootProject.java_version as Integer
|
||||||
}
|
}
|
||||||
|
options.encoding = "UTF-8"
|
||||||
}
|
}
|
||||||
|
|
||||||
java {
|
java {
|
||||||
withSourcesJar()
|
withSourcesJar()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p == project(":core") || p == project(":common")) {
|
// Disable running common
|
||||||
|
if (p == project(":common")) {
|
||||||
runClient.enabled = false
|
runClient.enabled = false
|
||||||
runServer.enabled = false
|
runServer.enabled = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Delete the merged folder when running clean
|
||||||
|
task cleanMergedJars() {
|
||||||
|
def mergedFolder = file("Merged")
|
||||||
|
if (mergedFolder.exists()) {
|
||||||
|
delete(mergedFolder)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// add cleanMergedJars to the end of the "clean" task
|
||||||
|
tasks["clean"].finalizedBy(cleanMergedJars)
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
MC_VERSION_1_18_2=
|
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
#!/usr/bin/env sh
|
||||||
|
|
||||||
|
buildVersion()
|
||||||
|
{
|
||||||
|
./gradlew clean -PmcVer=$1 --no-daemon
|
||||||
|
./gradlew build -PmcVer=$1 --no-daemon
|
||||||
|
}
|
||||||
|
|
||||||
|
buildVersion 1.19
|
||||||
|
buildVersion 1.18.2
|
||||||
|
buildVersion 1.18.1
|
||||||
|
buildVersion 1.17.1
|
||||||
|
buildVersion 1.16.5
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
@echo off
|
||||||
|
|
||||||
|
SETLOCAL
|
||||||
|
CALL :buildVersion "1.19"
|
||||||
|
CALL :buildVersion "1.18.2"
|
||||||
|
CALL :buildVersion "1.18.1"
|
||||||
|
CALL :buildVersion "1.17.1"
|
||||||
|
CALL :buildVersion "1.16.5"
|
||||||
|
EXIT /B %ERRORLEVEL%
|
||||||
|
|
||||||
|
:buildVersion
|
||||||
|
@echo on
|
||||||
|
call ./gradlew.bat clean -PmcVer="%~1" --no-daemon
|
||||||
|
call ./gradlew.bat build -PmcVer="%~1" --no-daemon
|
||||||
|
@echo off
|
||||||
|
EXIT /B 0
|
||||||
+15
-11
@@ -1,16 +1,20 @@
|
|||||||
loom {
|
|
||||||
accessWidenerPath.set(file("src/main/resources/lod.accesswidener"))
|
|
||||||
}
|
|
||||||
|
|
||||||
architectury {
|
architectury {
|
||||||
common()
|
common(rootProject.enabled_platforms.split(","))
|
||||||
}
|
}
|
||||||
|
|
||||||
afterEvaluate {
|
loom {
|
||||||
tasks {
|
accessWidenerPath = file("src/main/resources/lod.accesswidener")
|
||||||
remapJar {
|
}
|
||||||
remapAccessWidener.set(false)
|
|
||||||
}
|
dependencies {
|
||||||
|
// We depend on fabric loader here to use the fabric @Environment annotations and get the mixin dependencies
|
||||||
|
// Do NOT use other classes from fabric loader
|
||||||
|
modImplementation "net.fabricmc:fabric-loader:${rootProject.fabric_loader_version}"
|
||||||
|
|
||||||
|
if (minecraft_version == "1.16.5") {
|
||||||
|
modApi("me.shedaniel:architectury:${rootProject.architectury_version}")
|
||||||
|
} else {
|
||||||
|
modApi("dev.architectury:architectury:${rootProject.architectury_version}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -26,4 +30,4 @@ publishing {
|
|||||||
repositories {
|
repositories {
|
||||||
// Add repositories to publish to here.
|
// Add repositories to publish to here.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,402 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of the Distant Horizon mod (formerly the LOD Mod),
|
|
||||||
* licensed under the GNU GPL v3 License.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2020 James Seibel
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU 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 General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.seibel.lod.common;
|
|
||||||
|
|
||||||
import com.seibel.lod.core.config.*;
|
|
||||||
import com.seibel.lod.core.enums.config.*;
|
|
||||||
import com.seibel.lod.core.enums.rendering.*;
|
|
||||||
import com.seibel.lod.core.wrapperInterfaces.config.ILodConfigWrapperSingleton;
|
|
||||||
import com.seibel.lod.core.wrapperInterfaces.config.ILodConfigWrapperSingleton.IClient.IAdvanced.*;
|
|
||||||
import com.seibel.lod.core.wrapperInterfaces.config.ILodConfigWrapperSingleton.IClient.IGraphics.*;
|
|
||||||
import com.seibel.lod.core.wrapperInterfaces.config.ILodConfigWrapperSingleton.IClient.IGraphics.IFogQuality.IAdvancedFog;
|
|
||||||
import com.seibel.lod.core.wrapperInterfaces.config.ILodConfigWrapperSingleton.IClient.IGraphics.IFogQuality.IAdvancedFog.IHeightFog;
|
|
||||||
import com.seibel.lod.core.wrapperInterfaces.config.ILodConfigWrapperSingleton.IClient.IMultiplayer;
|
|
||||||
import com.seibel.lod.core.wrapperInterfaces.config.ILodConfigWrapperSingleton.IClient.IWorldGenerator;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This handles any configuration the user has access to.
|
|
||||||
* @author coolGi2007
|
|
||||||
* @version 12-12-2021
|
|
||||||
*/
|
|
||||||
|
|
||||||
public class Config
|
|
||||||
//public class Config extends TinyConfig
|
|
||||||
{
|
|
||||||
// CONFIG STRUCTURE
|
|
||||||
// -> Client
|
|
||||||
// |
|
|
||||||
// |-> Graphics
|
|
||||||
// | |-> Quality
|
|
||||||
// | |-> FogQuality
|
|
||||||
// | |-> AdvancedGraphics
|
|
||||||
// |
|
|
||||||
// |-> World Generation
|
|
||||||
// |
|
|
||||||
// |-> Advanced
|
|
||||||
// |-> Threads
|
|
||||||
// |-> Buffers
|
|
||||||
// |-> Debugging
|
|
||||||
|
|
||||||
// Since the original config system uses forge stuff, that means we have to rewrite the whole config system
|
|
||||||
|
|
||||||
@ConfigAnnotations.ScreenEntry
|
|
||||||
public static Client client;
|
|
||||||
|
|
||||||
@ConfigAnnotations.FileComment
|
|
||||||
public static String _optionsButton = ILodConfigWrapperSingleton.IClient.OPTIONS_BUTTON_DESC;
|
|
||||||
// I know this option should be in Client
|
|
||||||
// This is a hacky method to not show the button in the options screen but show it in the mod menu
|
|
||||||
// Tough it is in client in the wrapper singleton
|
|
||||||
@ConfigAnnotations.Entry
|
|
||||||
public static boolean optionsButton = true;
|
|
||||||
|
|
||||||
public static class Client
|
|
||||||
{
|
|
||||||
@ConfigAnnotations.ScreenEntry
|
|
||||||
public static Graphics graphics;
|
|
||||||
|
|
||||||
@ConfigAnnotations.ScreenEntry
|
|
||||||
public static WorldGenerator worldGenerator;
|
|
||||||
|
|
||||||
@ConfigAnnotations.ScreenEntry
|
|
||||||
public static Multiplayer multiplayer;
|
|
||||||
|
|
||||||
@ConfigAnnotations.ScreenEntry
|
|
||||||
public static Advanced advanced;
|
|
||||||
|
|
||||||
|
|
||||||
public static class Graphics
|
|
||||||
{
|
|
||||||
@ConfigAnnotations.ScreenEntry
|
|
||||||
public static Quality quality;
|
|
||||||
|
|
||||||
@ConfigAnnotations.ScreenEntry
|
|
||||||
public static FogQuality fogQuality;
|
|
||||||
|
|
||||||
@ConfigAnnotations.ScreenEntry
|
|
||||||
public static AdvancedGraphics advancedGraphics;
|
|
||||||
|
|
||||||
|
|
||||||
public static class Quality
|
|
||||||
{
|
|
||||||
@ConfigAnnotations.FileComment
|
|
||||||
public static String _drawResolution = IQuality.DRAW_RESOLUTION_DESC;
|
|
||||||
@ConfigAnnotations.Entry
|
|
||||||
public static HorizontalResolution drawResolution = IQuality.DRAW_RESOLUTION_DEFAULT;
|
|
||||||
|
|
||||||
@ConfigAnnotations.FileComment
|
|
||||||
public static String _lodChunkRenderDistance = IQuality.LOD_CHUNK_RENDER_DISTANCE_DESC;
|
|
||||||
@ConfigAnnotations.Entry(minValue = 16, maxValue = 2048)
|
|
||||||
public static int lodChunkRenderDistance = IQuality.LOD_CHUNK_RENDER_DISTANCE_MIN_DEFAULT_MAX.defaultValue;
|
|
||||||
|
|
||||||
@ConfigAnnotations.FileComment
|
|
||||||
public static String _verticalQuality = IQuality.VERTICAL_QUALITY_DESC;
|
|
||||||
@ConfigAnnotations.Entry
|
|
||||||
public static VerticalQuality verticalQuality = IQuality.VERTICAL_QUALITY_DEFAULT;
|
|
||||||
|
|
||||||
@ConfigAnnotations.FileComment
|
|
||||||
public static String _horizontalScale = IQuality.HORIZONTAL_SCALE_DESC;
|
|
||||||
@ConfigAnnotations.Entry(minValue = 2, maxValue = 32)
|
|
||||||
public static int horizontalScale = IQuality.HORIZONTAL_SCALE_MIN_DEFAULT_MAX.defaultValue;
|
|
||||||
|
|
||||||
@ConfigAnnotations.FileComment
|
|
||||||
public static String _horizontalQuality = IQuality.HORIZONTAL_SCALE_DESC;
|
|
||||||
@ConfigAnnotations.Entry
|
|
||||||
public static HorizontalQuality horizontalQuality = IQuality.HORIZONTAL_QUALITY_DEFAULT;
|
|
||||||
|
|
||||||
@ConfigAnnotations.FileComment
|
|
||||||
public static String _dropoffQuality = IQuality.DROPOFF_QUALITY_DESC;
|
|
||||||
@ConfigAnnotations.Entry
|
|
||||||
public static DropoffQuality dropoffQuality = IQuality.DROPOFF_QUALITY_DEFAULT;
|
|
||||||
|
|
||||||
@ConfigAnnotations.FileComment
|
|
||||||
public static String _lodBiomeBlending = IQuality.LOD_BIOME_BLENDING_DESC;
|
|
||||||
@ConfigAnnotations.Entry(minValue = 0, maxValue = 7)
|
|
||||||
public static int lodBiomeBlending = IQuality.LOD_BIOME_BLENDING_MIN_DEFAULT_MAX.defaultValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public static class FogQuality
|
|
||||||
{
|
|
||||||
@ConfigAnnotations.FileComment
|
|
||||||
public static String _fogDistance = IFogQuality.FOG_DISTANCE_DESC;
|
|
||||||
@ConfigAnnotations.Entry
|
|
||||||
public static FogDistance fogDistance = IFogQuality.FOG_DISTANCE_DEFAULT;
|
|
||||||
|
|
||||||
@ConfigAnnotations.FileComment
|
|
||||||
public static String _fogDrawMode = IFogQuality.FOG_DRAW_MODE_DESC;
|
|
||||||
@ConfigAnnotations.Entry
|
|
||||||
public static FogDrawMode fogDrawMode = IFogQuality.FOG_DRAW_MODE_DEFAULT;
|
|
||||||
|
|
||||||
@ConfigAnnotations.FileComment
|
|
||||||
public static String _fogColorMode = IFogQuality.FOG_COLOR_MODE_DESC;
|
|
||||||
@ConfigAnnotations.Entry
|
|
||||||
public static FogColorMode fogColorMode = IFogQuality.FOG_COLOR_MODE_DEFAULT;
|
|
||||||
|
|
||||||
@ConfigAnnotations.FileComment
|
|
||||||
public static String _disableVanillaFog = IFogQuality.DISABLE_VANILLA_FOG_DESC;
|
|
||||||
@ConfigAnnotations.Entry
|
|
||||||
public static boolean disableVanillaFog = IFogQuality.DISABLE_VANILLA_FOG_DEFAULT;
|
|
||||||
|
|
||||||
@ConfigAnnotations.ScreenEntry
|
|
||||||
public static AdvancedFog advancedFog;
|
|
||||||
|
|
||||||
public static class AdvancedFog {
|
|
||||||
static final double SQRT2 = 1.4142135623730951;
|
|
||||||
|
|
||||||
@ConfigAnnotations.FileComment
|
|
||||||
public static String _farFogStart = IAdvancedFog.FAR_FOG_START_DESC;
|
|
||||||
@ConfigAnnotations.Entry(minValue = 0.0, maxValue = SQRT2)
|
|
||||||
public static double farFogStart = IAdvancedFog.FAR_FOG_START_MIN_DEFAULT_MAX.defaultValue;
|
|
||||||
|
|
||||||
@ConfigAnnotations.FileComment
|
|
||||||
public static String _farFogEnd = IAdvancedFog.FAR_FOG_END_DESC;
|
|
||||||
@ConfigAnnotations.Entry(minValue = 0.0, maxValue = SQRT2)
|
|
||||||
public static double farFogEnd = IAdvancedFog.FAR_FOG_END_MIN_DEFAULT_MAX.defaultValue;
|
|
||||||
|
|
||||||
@ConfigAnnotations.FileComment
|
|
||||||
public static String _farFogMin = IAdvancedFog.FAR_FOG_MIN_DESC;
|
|
||||||
@ConfigAnnotations.Entry(minValue = -5.0, maxValue = SQRT2)
|
|
||||||
public static double farFogMin = IAdvancedFog.FAR_FOG_MIN_MIN_DEFAULT_MAX.defaultValue;
|
|
||||||
|
|
||||||
@ConfigAnnotations.FileComment
|
|
||||||
public static String _farFogMax = IAdvancedFog.FAR_FOG_MAX_DESC;
|
|
||||||
@ConfigAnnotations.Entry(minValue = 0.0, maxValue = 5.0)
|
|
||||||
public static double farFogMax = IAdvancedFog.FAR_FOG_MAX_MIN_DEFAULT_MAX.defaultValue;
|
|
||||||
|
|
||||||
@ConfigAnnotations.FileComment
|
|
||||||
public static String _farFogType = IAdvancedFog.FAR_FOG_TYPE_DESC;
|
|
||||||
@ConfigAnnotations.Entry
|
|
||||||
public static FogSetting.FogType farFogType = IAdvancedFog.FAR_FOG_TYPE_DEFAULT;
|
|
||||||
|
|
||||||
@ConfigAnnotations.FileComment
|
|
||||||
public static String _farFogDensity = IAdvancedFog.FAR_FOG_DENSITY_DESC;
|
|
||||||
@ConfigAnnotations.Entry(minValue = 0.01, maxValue = 50.0)
|
|
||||||
public static double farFogDensity = IAdvancedFog.FAR_FOG_DENSITY_MIN_DEFAULT_MAX.defaultValue;
|
|
||||||
|
|
||||||
@ConfigAnnotations.ScreenEntry
|
|
||||||
public static HeightFog heightFog;
|
|
||||||
|
|
||||||
public static class HeightFog {
|
|
||||||
|
|
||||||
@ConfigAnnotations.FileComment
|
|
||||||
public static String _heightFogMixMode = IHeightFog.HEIGHT_FOG_MIX_MODE_DESC;
|
|
||||||
@ConfigAnnotations.Entry
|
|
||||||
public static HeightFogMixMode heightFogMixMode = IHeightFog.HEIGHT_FOG_MIX_MODE_DEFAULT;
|
|
||||||
@ConfigAnnotations.FileComment
|
|
||||||
public static String _heightFogMode = IHeightFog.HEIGHT_FOG_MODE_DESC;
|
|
||||||
@ConfigAnnotations.Entry
|
|
||||||
public static HeightFogMode heightFogMode = IHeightFog.HEIGHT_FOG_MODE_DEFAULT;
|
|
||||||
|
|
||||||
@ConfigAnnotations.FileComment
|
|
||||||
public static String _heightFogHeight = IHeightFog.HEIGHT_FOG_HEIGHT_DESC;
|
|
||||||
@ConfigAnnotations.Entry(minValue = -4096.0, maxValue = 4096.0)
|
|
||||||
public static double heightFogHeight = IHeightFog.HEIGHT_FOG_HEIGHT_MIN_DEFAULT_MAX.defaultValue;
|
|
||||||
|
|
||||||
@ConfigAnnotations.FileComment
|
|
||||||
public static String _heightFogStart = IHeightFog.HEIGHT_FOG_START_DESC;
|
|
||||||
@ConfigAnnotations.Entry(minValue = 0.0, maxValue = SQRT2)
|
|
||||||
public static double heightFogStart = IHeightFog.HEIGHT_FOG_START_MIN_DEFAULT_MAX.defaultValue;
|
|
||||||
|
|
||||||
@ConfigAnnotations.FileComment
|
|
||||||
public static String _heightFogEnd = IHeightFog.HEIGHT_FOG_END_DESC;
|
|
||||||
@ConfigAnnotations.Entry(minValue = 0.0, maxValue = SQRT2)
|
|
||||||
public static double heightFogEnd = IHeightFog.HEIGHT_FOG_END_MIN_DEFAULT_MAX.defaultValue;
|
|
||||||
|
|
||||||
@ConfigAnnotations.FileComment
|
|
||||||
public static String _heightFogMin = IHeightFog.HEIGHT_FOG_MIN_DESC;
|
|
||||||
@ConfigAnnotations.Entry(minValue = -5.0, maxValue = SQRT2)
|
|
||||||
public static double heightFogMin = IHeightFog.HEIGHT_FOG_MIN_MIN_DEFAULT_MAX.defaultValue;
|
|
||||||
|
|
||||||
@ConfigAnnotations.FileComment
|
|
||||||
public static String _heightFogMax = IHeightFog.HEIGHT_FOG_MAX_DESC;
|
|
||||||
@ConfigAnnotations.Entry(minValue = 0.0, maxValue = 5.0)
|
|
||||||
public static double heightFogMax = IHeightFog.HEIGHT_FOG_MAX_MIN_DEFAULT_MAX.defaultValue;
|
|
||||||
|
|
||||||
@ConfigAnnotations.FileComment
|
|
||||||
public static String _heightFogType = IHeightFog.HEIGHT_FOG_TYPE_DESC;
|
|
||||||
@ConfigAnnotations.Entry
|
|
||||||
public static FogSetting.FogType heightFogType = IHeightFog.HEIGHT_FOG_TYPE_DEFAULT;
|
|
||||||
|
|
||||||
@ConfigAnnotations.FileComment
|
|
||||||
public static String _heightFogDensity = IHeightFog.HEIGHT_FOG_DENSITY_DESC;
|
|
||||||
@ConfigAnnotations.Entry(minValue = 0.01, maxValue = 50.0)
|
|
||||||
public static double heightFogDensity = IHeightFog.HEIGHT_FOG_DENSITY_MIN_DEFAULT_MAX.defaultValue;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public static class AdvancedGraphics
|
|
||||||
{
|
|
||||||
@ConfigAnnotations.FileComment
|
|
||||||
public static String _disableDirectionalCulling = IAdvancedGraphics.DISABLE_DIRECTIONAL_CULLING_DESC;
|
|
||||||
@ConfigAnnotations.Entry
|
|
||||||
public static boolean disableDirectionalCulling = IAdvancedGraphics.DISABLE_DIRECTIONAL_CULLING_DEFAULT;
|
|
||||||
|
|
||||||
@ConfigAnnotations.FileComment
|
|
||||||
public static String _vanillaOverdraw = IAdvancedGraphics.VANILLA_OVERDRAW_DESC;
|
|
||||||
@ConfigAnnotations.Entry
|
|
||||||
public static VanillaOverdraw vanillaOverdraw = IAdvancedGraphics.VANILLA_OVERDRAW_DEFAULT;
|
|
||||||
|
|
||||||
@ConfigAnnotations.FileComment
|
|
||||||
public static String _useExtendedNearClipPlane = IAdvancedGraphics.USE_EXTENDED_NEAR_CLIP_PLANE_DESC;
|
|
||||||
@ConfigAnnotations.Entry
|
|
||||||
public static boolean useExtendedNearClipPlane = IAdvancedGraphics.USE_EXTENDED_NEAR_CLIP_PLANE_DEFAULT;
|
|
||||||
|
|
||||||
@ConfigAnnotations.FileComment
|
|
||||||
public static String _brightnessMultiplier = IAdvancedGraphics.BRIGHTNESS_MULTIPLIER_DESC;
|
|
||||||
@ConfigAnnotations.Entry
|
|
||||||
public static double brightnessMultiplier = IAdvancedGraphics.BRIGHTNESS_MULTIPLIER_DEFAULT;
|
|
||||||
|
|
||||||
@ConfigAnnotations.FileComment
|
|
||||||
public static String _saturationMultiplier = IAdvancedGraphics.SATURATION_MULTIPLIER_DESC;
|
|
||||||
@ConfigAnnotations.Entry
|
|
||||||
public static double saturationMultiplier = IAdvancedGraphics.SATURATION_MULTIPLIER_DEFAULT;
|
|
||||||
|
|
||||||
/*
|
|
||||||
@ConfigAnnotations.FileComment
|
|
||||||
public static String _backsideCullingRange = IAdvancedGraphics.VANILLA_CULLING_RANGE_DESC;
|
|
||||||
@ConfigAnnotations.Entry(minValue = 0, maxValue = 512)
|
|
||||||
public static int backsideCullingRange = IAdvancedGraphics.VANILLA_CULLING_RANGE_MIN_DEFAULT_MAX.defaultValue;
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public static class WorldGenerator
|
|
||||||
{
|
|
||||||
@ConfigAnnotations.FileComment
|
|
||||||
public static String _enableDistantGeneration = IWorldGenerator.ENABLE_DISTANT_GENERATION_DESC;
|
|
||||||
@ConfigAnnotations.Entry
|
|
||||||
public static boolean enableDistantGeneration = IWorldGenerator.ENABLE_DISTANT_GENERATION_DEFAULT;
|
|
||||||
|
|
||||||
// @ConfigAnnotations.FileComment
|
|
||||||
// public static String _distanceGenerationMode = IWorldGenerator.getDistanceGenerationModeDesc();
|
|
||||||
@ConfigAnnotations.Entry
|
|
||||||
public static DistanceGenerationMode distanceGenerationMode = IWorldGenerator.DISTANCE_GENERATION_MODE_DEFAULT;
|
|
||||||
|
|
||||||
@ConfigAnnotations.FileComment
|
|
||||||
public static String _lightGenerationMode = IWorldGenerator.LIGHT_GENERATION_MODE_DESC;
|
|
||||||
@ConfigAnnotations.Entry
|
|
||||||
public static LightGenerationMode lightGenerationMode = IWorldGenerator.LIGHT_GENERATION_MODE_DEFAULT;
|
|
||||||
|
|
||||||
@ConfigAnnotations.FileComment
|
|
||||||
public static String _generationPriority = IWorldGenerator.GENERATION_PRIORITY_DESC;
|
|
||||||
@ConfigAnnotations.Entry
|
|
||||||
public static GenerationPriority generationPriority = IWorldGenerator.GENERATION_PRIORITY_DEFAULT;
|
|
||||||
|
|
||||||
/*
|
|
||||||
@ConfigAnnotations.FileComment
|
|
||||||
public static String _allowUnstableFeatureGeneration = IWorldGenerator.ALLOW_UNSTABLE_FEATURE_GENERATION_DESC;
|
|
||||||
// FIXME: Temperary override. In 1.18, the newer Unstable gnerator is more usable
|
|
||||||
@ConfigAnnotations.Entry
|
|
||||||
public static boolean allowUnstableFeatureGeneration = true;//IWorldGenerator.ALLOW_UNSTABLE_FEATURE_GENERATION_DEFAULT;
|
|
||||||
*/
|
|
||||||
|
|
||||||
@ConfigAnnotations.FileComment
|
|
||||||
public static String _blocksToAvoid = IWorldGenerator.BLOCKS_TO_AVOID_DESC;
|
|
||||||
@ConfigAnnotations.Entry
|
|
||||||
public static BlocksToAvoid blocksToAvoid = IWorldGenerator.BLOCKS_TO_AVOID_DEFAULT;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public static class Multiplayer
|
|
||||||
{
|
|
||||||
@ConfigAnnotations.FileComment
|
|
||||||
public static String _serverFolderNameMode = IMultiplayer.SERVER_FOLDER_NAME_MODE_DESC;
|
|
||||||
@ConfigAnnotations.Entry
|
|
||||||
public static ServerFolderNameMode serverFolderNameMode = IMultiplayer.SERVER_FOLDER_NAME_MODE_DEFAULT;
|
|
||||||
|
|
||||||
@ConfigAnnotations.FileComment
|
|
||||||
public static String _multiDimensionRequiredSimilarity = IMultiplayer.MULTI_DIMENSION_REQUIRED_SIMILARITY_DESC;
|
|
||||||
@ConfigAnnotations.Entry
|
|
||||||
public static double multiDimensionRequiredSimilarity = IMultiplayer.MULTI_DIMENSION_REQUIRED_SIMILARITY_DEFAULT;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public static class Advanced
|
|
||||||
{
|
|
||||||
@ConfigAnnotations.ScreenEntry
|
|
||||||
public static Threading threading;
|
|
||||||
|
|
||||||
@ConfigAnnotations.ScreenEntry
|
|
||||||
public static Debugging debugging;
|
|
||||||
|
|
||||||
@ConfigAnnotations.ScreenEntry
|
|
||||||
public static Buffers buffers;
|
|
||||||
|
|
||||||
|
|
||||||
public static class Threading
|
|
||||||
{
|
|
||||||
@ConfigAnnotations.FileComment
|
|
||||||
public static String _numberOfWorldGenerationThreads = IThreading.NUMBER_OF_WORLD_GENERATION_THREADS_DESC;
|
|
||||||
@ConfigAnnotations.Entry(minValue = 1, maxValue = 50)
|
|
||||||
public static int numberOfWorldGenerationThreads = IThreading.NUMBER_OF_WORLD_GENERATION_THREADS_DEFAULT.defaultValue;
|
|
||||||
|
|
||||||
@ConfigAnnotations.FileComment
|
|
||||||
public static String _numberOfBufferBuilderThreads = IThreading.NUMBER_OF_BUFFER_BUILDER_THREADS_DESC;
|
|
||||||
@ConfigAnnotations.Entry(minValue = 1, maxValue = 50)
|
|
||||||
public static int numberOfBufferBuilderThreads = IThreading.NUMBER_OF_BUFFER_BUILDER_THREADS_MIN_DEFAULT_MAX.defaultValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public static class Debugging
|
|
||||||
{
|
|
||||||
@ConfigAnnotations.FileComment
|
|
||||||
public static String _drawLods = IDebugging.DRAW_LODS_DESC;
|
|
||||||
@ConfigAnnotations.Entry
|
|
||||||
public static boolean drawLods = IDebugging.DRAW_LODS_DEFAULT;
|
|
||||||
|
|
||||||
@ConfigAnnotations.FileComment
|
|
||||||
public static String _debugMode = IDebugging.DEBUG_MODE_DESC;
|
|
||||||
@ConfigAnnotations.Entry
|
|
||||||
public static DebugMode debugMode = IDebugging.DEBUG_MODE_DEFAULT;
|
|
||||||
|
|
||||||
@ConfigAnnotations.FileComment
|
|
||||||
public static String _enableDebugKeybindings = IDebugging.DEBUG_KEYBINDINGS_ENABLED_DESC;
|
|
||||||
@ConfigAnnotations.Entry
|
|
||||||
public static boolean enableDebugKeybindings = IDebugging.DEBUG_KEYBINDINGS_ENABLED_DEFAULT;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public static class Buffers
|
|
||||||
{
|
|
||||||
@ConfigAnnotations.FileComment
|
|
||||||
public static String _gpuUploadMethod = IBuffers.GPU_UPLOAD_METHOD_DESC;
|
|
||||||
@ConfigAnnotations.Entry
|
|
||||||
public static GpuUploadMethod gpuUploadMethod = IBuffers.GPU_UPLOAD_METHOD_DEFAULT;
|
|
||||||
|
|
||||||
@ConfigAnnotations.FileComment
|
|
||||||
public static String _gpuUploadPerMegabyteInMilliseconds = IBuffers.GPU_UPLOAD_PER_MEGABYTE_IN_MILLISECONDS_DESC;
|
|
||||||
@ConfigAnnotations.Entry(minValue = 0, maxValue = 50)
|
|
||||||
public static int gpuUploadPerMegabyteInMilliseconds = IBuffers.GPU_UPLOAD_PER_MEGABYTE_IN_MILLISECONDS_DEFAULT.defaultValue;
|
|
||||||
|
|
||||||
@ConfigAnnotations.FileComment
|
|
||||||
public static String _rebuildTimes = IBuffers.REBUILD_TIMES_DESC;
|
|
||||||
@ConfigAnnotations.Entry
|
|
||||||
public static BufferRebuildTimes rebuildTimes = IBuffers.REBUILD_TIMES_DEFAULT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,9 +1,30 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
|
||||||
|
* licensed under the GNU LGPL v3 License.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2020-2022 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.lod.common;
|
package com.seibel.lod.common;
|
||||||
|
|
||||||
import com.seibel.lod.common.forge.LodForgeMethodCaller;
|
import com.seibel.lod.common.forge.LodForgeMethodCaller;
|
||||||
import com.seibel.lod.common.networking.NetworkInterface;
|
|
||||||
import com.seibel.lod.common.wrappers.DependencySetup;
|
import com.seibel.lod.common.wrappers.DependencySetup;
|
||||||
import com.seibel.lod.common.wrappers.config.ConfigGui;
|
import com.seibel.lod.core.ModInfo;
|
||||||
|
import com.seibel.lod.core.api.internal.SharedApi;
|
||||||
|
import com.seibel.lod.core.config.Config;
|
||||||
|
import com.seibel.lod.core.config.ConfigBase;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is the common main class
|
* This is the common main class
|
||||||
@@ -11,29 +32,23 @@ import com.seibel.lod.common.wrappers.config.ConfigGui;
|
|||||||
*/
|
*/
|
||||||
public class LodCommonMain {
|
public class LodCommonMain {
|
||||||
public static boolean forge = false;
|
public static boolean forge = false;
|
||||||
public static boolean serverSided;
|
|
||||||
public static LodForgeMethodCaller forgeMethodCaller;
|
public static LodForgeMethodCaller forgeMethodCaller;
|
||||||
public static NetworkInterface networkInterface;
|
public static void startup(LodForgeMethodCaller caller) {
|
||||||
|
|
||||||
public static void startup(LodForgeMethodCaller caller, boolean serverSided, NetworkInterface networkInterface) {
|
|
||||||
LodCommonMain.serverSided = serverSided;
|
|
||||||
if (caller != null) {
|
if (caller != null) {
|
||||||
LodCommonMain.forge = true;
|
LodCommonMain.forge = true;
|
||||||
forgeMethodCaller = caller;
|
forgeMethodCaller = caller;
|
||||||
}
|
}
|
||||||
|
|
||||||
DependencySetup.createInitialBindings();
|
DependencySetup.createSharedBindings();
|
||||||
|
SharedApi.init();
|
||||||
LodCommonMain.networkInterface = networkInterface;
|
// if (!serverSided) {
|
||||||
if (!serverSided) {
|
// new NetworkReceiver().register_Client();
|
||||||
networkInterface.register_Client();
|
// } else {
|
||||||
} else {
|
// new NetworkReceiver().register_Server();
|
||||||
networkInterface.register_Server();
|
// }
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static void initConfig() {
|
public static void initConfig() {
|
||||||
ConfigGui.init(Config.class);
|
ConfigBase.INSTANCE = new ConfigBase(ModInfo.ID, ModInfo.NAME, Config.class,1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,32 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
|
||||||
|
* licensed under the GNU LGPL v3 License.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2020-2022 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.lod.common.forge;
|
package com.seibel.lod.common.forge;
|
||||||
|
|
||||||
import com.seibel.lod.common.wrappers.minecraft.MinecraftClientWrapper;
|
import com.seibel.lod.common.wrappers.minecraft.MinecraftClientWrapper;
|
||||||
import net.minecraft.client.renderer.block.model.BakedQuad;
|
import net.minecraft.client.renderer.block.model.BakedQuad;
|
||||||
import net.minecraft.core.Direction;
|
import net.minecraft.core.Direction;
|
||||||
|
#if POST_MC_1_19
|
||||||
|
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.Block;
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
|
|
||||||
@@ -15,5 +39,11 @@ import java.util.Random;
|
|||||||
* @author Ran
|
* @author Ran
|
||||||
*/
|
*/
|
||||||
public interface LodForgeMethodCaller {
|
public interface LodForgeMethodCaller {
|
||||||
List<BakedQuad> getQuads(MinecraftClientWrapper mc, Block block, BlockState blockState, Direction direction, Random random);
|
#if PRE_MC_1_19
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,27 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
|
||||||
|
* licensed under the GNU LGPL v3 License.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2020-2022 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.lod.common.networking;
|
package com.seibel.lod.common.networking;
|
||||||
|
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.multiplayer.ClientPacketListener;
|
|
||||||
import net.minecraft.network.FriendlyByteBuf;
|
import net.minecraft.network.FriendlyByteBuf;
|
||||||
import net.minecraft.server.MinecraftServer;
|
import net.minecraft.world.entity.player.Player;
|
||||||
import net.minecraft.server.level.ServerPlayer;
|
|
||||||
import net.minecraft.server.network.ServerGamePacketListenerImpl;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is packet handler for our mod
|
* This is packet handler for our mod
|
||||||
@@ -13,18 +29,15 @@ import net.minecraft.server.network.ServerGamePacketListenerImpl;
|
|||||||
*
|
*
|
||||||
* @author Ran
|
* @author Ran
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// TODO: Server sided stuff here
|
||||||
public class NetworkHandler {
|
public class NetworkHandler {
|
||||||
// If you need the response sender then tell me
|
public static void receivePacketClient(Minecraft client, FriendlyByteBuf buf, Player player) {
|
||||||
// I'll add extra code to get the response sender
|
// This just exists here for testing purposes, it'll be removed in the future
|
||||||
public static void receivePacketClient(Minecraft client, ClientPacketListener handler, FriendlyByteBuf buf) {
|
System.out.println("Received int " + buf.readInt());
|
||||||
// TODO: Server sided stuff here
|
|
||||||
// You can make client execute something by using client.execute(Runnable)
|
|
||||||
// In the fabric docs it says that client.execute is ran on the render thread?
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If you need the response sender then tell me
|
public static void receivePacketServer(FriendlyByteBuf buf, Player player) {
|
||||||
// I'll add extra code to get the response sender
|
|
||||||
public static void receivePacketServer(MinecraftServer server, ServerPlayer client, ServerGamePacketListenerImpl handler, FriendlyByteBuf buf) {
|
|
||||||
// TODO: Server sided stuff here
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +0,0 @@
|
|||||||
package com.seibel.lod.common.networking;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Ran
|
|
||||||
*/
|
|
||||||
public interface NetworkInterface {
|
|
||||||
void register_Client();
|
|
||||||
void register_Server();
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
|
||||||
|
* licensed under the GNU LGPL v3 License.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2020-2022 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.lod.common.networking;
|
||||||
|
|
||||||
|
#if MC_1_16_5
|
||||||
|
import me.shedaniel.architectury.networking.NetworkManager;
|
||||||
|
#else
|
||||||
|
import dev.architectury.networking.NetworkManager;
|
||||||
|
#endif
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.network.FriendlyByteBuf;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Ran
|
||||||
|
*/
|
||||||
|
// Comment: What does the 'server' side mean? Dedicated server? Or does it include the internal server?
|
||||||
|
// (I removed the hookup that calls the register method, since I'm not sure what it is doing yet)
|
||||||
|
public class NetworkReceiver {
|
||||||
|
public void register_Client() {
|
||||||
|
NetworkManager.registerReceiver(NetworkManager.serverToClient(), Networking.RESOURCE_LOCATION, new ClientReceiver());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void register_Server() {
|
||||||
|
NetworkManager.registerReceiver(NetworkManager.clientToServer(), Networking.RESOURCE_LOCATION, new ServerReceiver());
|
||||||
|
}
|
||||||
|
|
||||||
|
static class ServerReceiver implements NetworkManager.NetworkReceiver {
|
||||||
|
@Override
|
||||||
|
public void receive(FriendlyByteBuf buf, NetworkManager.PacketContext context) {
|
||||||
|
com.seibel.lod.common.networking.NetworkHandler.receivePacketServer(buf, context.getPlayer());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static class ClientReceiver implements NetworkManager.NetworkReceiver {
|
||||||
|
@Override
|
||||||
|
public void receive(FriendlyByteBuf buf, NetworkManager.PacketContext context) {
|
||||||
|
com.seibel.lod.common.networking.NetworkHandler.receivePacketClient(Minecraft.getInstance(), buf, context.getPlayer());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,30 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
|
||||||
|
* licensed under the GNU LGPL v3 License.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2020-2022 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.lod.common.networking;
|
package com.seibel.lod.common.networking;
|
||||||
|
|
||||||
import com.seibel.lod.core.ModInfo;
|
import com.seibel.lod.core.ModInfo;
|
||||||
|
#if MC_1_16_5
|
||||||
|
import me.shedaniel.architectury.networking.NetworkManager;
|
||||||
|
#else
|
||||||
|
import dev.architectury.networking.NetworkManager;
|
||||||
|
#endif
|
||||||
import io.netty.buffer.Unpooled;
|
import io.netty.buffer.Unpooled;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.network.FriendlyByteBuf;
|
import net.minecraft.network.FriendlyByteBuf;
|
||||||
@@ -17,7 +41,7 @@ import java.util.Objects;
|
|||||||
* @author Ran
|
* @author Ran
|
||||||
*/
|
*/
|
||||||
public class Networking {
|
public class Networking {
|
||||||
public static final ResourceLocation resourceLocation_meow = new ResourceLocation("lod", "meow");
|
public static final ResourceLocation RESOURCE_LOCATION = new ResourceLocation("lod", "data");
|
||||||
|
|
||||||
public static FriendlyByteBuf createNew() {
|
public static FriendlyByteBuf createNew() {
|
||||||
// TODO: Probably replace the Unpooled.buffer()
|
// TODO: Probably replace the Unpooled.buffer()
|
||||||
@@ -26,11 +50,6 @@ public class Networking {
|
|||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* All code below is from the fabric api and might have been modified to work with Distant Horizons
|
|
||||||
* Which is licensed under the Apache License 2.0
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sends a packet to a player.
|
* Sends a packet to a player.
|
||||||
*
|
*
|
||||||
@@ -38,11 +57,7 @@ public class Networking {
|
|||||||
* @param buf the payload of the packet.
|
* @param buf the payload of the packet.
|
||||||
*/
|
*/
|
||||||
public static void send(ServerPlayer player, FriendlyByteBuf buf) {
|
public static void send(ServerPlayer player, FriendlyByteBuf buf) {
|
||||||
Objects.requireNonNull(player, "Server player entity cannot be null");
|
NetworkManager.sendToPlayer(player, RESOURCE_LOCATION, buf);
|
||||||
Objects.requireNonNull(resourceLocation_meow, "Channel name cannot be null");
|
|
||||||
Objects.requireNonNull(buf, "Packet byte buf cannot be null");
|
|
||||||
|
|
||||||
player.connection.send(createS2CPacket(resourceLocation_meow, buf));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -52,49 +67,7 @@ public class Networking {
|
|||||||
* @throws IllegalStateException if the client is not connected to a server
|
* @throws IllegalStateException if the client is not connected to a server
|
||||||
*/
|
*/
|
||||||
public static void send(FriendlyByteBuf buf) throws IllegalStateException {
|
public static void send(FriendlyByteBuf buf) throws IllegalStateException {
|
||||||
// You cant send without a client player, so this is fine
|
NetworkManager.sendToServer(RESOURCE_LOCATION, buf);
|
||||||
if (Minecraft.getInstance().getConnection() != null) {
|
|
||||||
Minecraft.getInstance().getConnection().send(createC2SPacket(resourceLocation_meow, buf));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new IllegalStateException("Cannot send packets when not in game!");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a packet which may be sent to the connected client.
|
|
||||||
*
|
|
||||||
* @param channelName the channel name
|
|
||||||
* @param buf the packet byte buf which represents the payload of the packet
|
|
||||||
* @return a new packet
|
|
||||||
*/
|
|
||||||
public static Packet<?> createS2CPacket(ResourceLocation channelName, FriendlyByteBuf buf) {
|
|
||||||
Objects.requireNonNull(channelName, "Channel cannot be null");
|
|
||||||
Objects.requireNonNull(buf, "Buf cannot be null");
|
|
||||||
|
|
||||||
return createPlayS2CPacket(channelName, buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Packet<?> createPlayS2CPacket(ResourceLocation channel, FriendlyByteBuf buf) {
|
|
||||||
return new ClientboundCustomPayloadPacket(channel, buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a packet which may be sent to a the connected server.
|
|
||||||
*
|
|
||||||
* @param channelName the channel name
|
|
||||||
* @param buf the packet byte buf which represents the payload of the packet
|
|
||||||
* @return a new packet
|
|
||||||
*/
|
|
||||||
public static Packet<?> createC2SPacket(ResourceLocation channelName, FriendlyByteBuf buf) {
|
|
||||||
Objects.requireNonNull(channelName, "Channel name cannot be null");
|
|
||||||
Objects.requireNonNull(buf, "Buf cannot be null");
|
|
||||||
|
|
||||||
return createPlayC2SPacket(channelName, buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Packet<?> createPlayC2SPacket(ResourceLocation channelName, FriendlyByteBuf buf) {
|
|
||||||
return new ServerboundCustomPayloadPacket(channelName, buf);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,15 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
|
||||||
|
* licensed under the GNU LGPL v3 License.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2020-2022 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.lod.common.wrappers;
|
package com.seibel.lod.common.wrappers;
|
||||||
|
|
||||||
import com.seibel.lod.common.LodCommonMain;
|
import com.seibel.lod.common.wrappers.gui.LangWrapper;
|
||||||
|
import com.seibel.lod.common.wrappers.minecraft.MinecraftDedicatedServerWrapper;
|
||||||
|
import com.seibel.lod.core.wrapperInterfaces.config.ILangWrapper;
|
||||||
import com.seibel.lod.common.wrappers.minecraft.MinecraftClientWrapper;
|
import com.seibel.lod.common.wrappers.minecraft.MinecraftClientWrapper;
|
||||||
import com.seibel.lod.common.wrappers.minecraft.MinecraftRenderWrapper;
|
import com.seibel.lod.common.wrappers.minecraft.MinecraftRenderWrapper;
|
||||||
import com.seibel.lod.core.handlers.IReflectionHandler;
|
import com.seibel.lod.core.IReflectionHandler;
|
||||||
import com.seibel.lod.core.handlers.ReflectionHandler;
|
import com.seibel.lod.core.ReflectionHandler;
|
||||||
import com.seibel.lod.core.handlers.dependencyInjection.SingletonHandler;
|
import com.seibel.lod.core.dependencyInjection.SingletonInjector;
|
||||||
import com.seibel.lod.core.wrapperInterfaces.IVersionConstants;
|
import com.seibel.lod.core.wrapperInterfaces.IVersionConstants;
|
||||||
import com.seibel.lod.core.wrapperInterfaces.IWrapperFactory;
|
import com.seibel.lod.core.wrapperInterfaces.IWrapperFactory;
|
||||||
|
import com.seibel.lod.core.wrapperInterfaces.config.ILodConfigWrapperSingleton;
|
||||||
|
import com.seibel.lod.core.wrapperInterfaces.config.LodConfigWrapperSingleton;
|
||||||
import com.seibel.lod.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
|
import com.seibel.lod.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
|
||||||
import com.seibel.lod.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
|
import com.seibel.lod.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
|
||||||
|
import com.seibel.lod.core.wrapperInterfaces.minecraft.IMinecraftSharedWrapper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Binds all necessary dependencies, so we
|
* Binds all necessary dependencies, so we
|
||||||
@@ -22,17 +46,25 @@ import com.seibel.lod.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
|
|||||||
* @version 12-1-2021
|
* @version 12-1-2021
|
||||||
*/
|
*/
|
||||||
public class DependencySetup {
|
public class DependencySetup {
|
||||||
public static void createInitialBindings()
|
public static void createSharedBindings()
|
||||||
{
|
{
|
||||||
SingletonHandler.bind(IVersionConstants.class, VersionConstants.INSTANCE);
|
SingletonInjector.INSTANCE.bind(ILodConfigWrapperSingleton.class, LodConfigWrapperSingleton.INSTANCE); // TODO: Remove
|
||||||
if (!LodCommonMain.serverSided)
|
SingletonInjector.INSTANCE.bind(ILangWrapper.class, LangWrapper.INSTANCE);
|
||||||
{
|
SingletonInjector.INSTANCE.bind(IVersionConstants.class, VersionConstants.INSTANCE);
|
||||||
SingletonHandler.bind(IMinecraftClientWrapper.class, MinecraftClientWrapper.INSTANCE);
|
SingletonInjector.INSTANCE.bind(IWrapperFactory.class, WrapperFactory.INSTANCE);
|
||||||
SingletonHandler.bind(IMinecraftRenderWrapper.class, MinecraftRenderWrapper.INSTANCE);
|
|
||||||
SingletonHandler.bind(IReflectionHandler.class, ReflectionHandler.createSingleton(MinecraftClientWrapper.INSTANCE.getOptions().getClass().getDeclaredFields(), MinecraftClientWrapper.INSTANCE.getOptions()));
|
|
||||||
}
|
|
||||||
|
|
||||||
SingletonHandler.bind(IWrapperFactory.class, WrapperFactory.INSTANCE);
|
|
||||||
DependencySetupDoneCheck.isDone = true;
|
DependencySetupDoneCheck.isDone = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//@Environment(EnvType.SERVER)
|
||||||
|
public static void createServerBindings() {
|
||||||
|
SingletonInjector.INSTANCE.bind(IMinecraftSharedWrapper.class, MinecraftDedicatedServerWrapper.INSTANCE);
|
||||||
|
}
|
||||||
|
|
||||||
|
//@Environment(EnvType.CLIENT)
|
||||||
|
public static void createClientBindings() {
|
||||||
|
SingletonInjector.INSTANCE.bind(IMinecraftClientWrapper.class, MinecraftClientWrapper.INSTANCE);
|
||||||
|
SingletonInjector.INSTANCE.bind(IMinecraftSharedWrapper.class, MinecraftClientWrapper.INSTANCE);
|
||||||
|
SingletonInjector.INSTANCE.bind(IMinecraftRenderWrapper.class, MinecraftRenderWrapper.INSTANCE);
|
||||||
|
SingletonInjector.INSTANCE.bind(IReflectionHandler.class, ReflectionHandler.INSTANCE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,22 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
|
||||||
|
* licensed under the GNU LGPL v3 License.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2020-2022 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.lod.common.wrappers;
|
package com.seibel.lod.common.wrappers;
|
||||||
|
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|||||||
@@ -1,34 +1,37 @@
|
|||||||
/*
|
/*
|
||||||
* This file is part of the Distant Horizon mod (formerly the LOD Mod),
|
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
|
||||||
* licensed under the GNU GPL v3 License.
|
* licensed under the GNU LGPL v3 License.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2020 James Seibel
|
* Copyright (C) 2020-2022 James Seibel
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
* the Free Software Foundation, version 3.
|
* the Free Software Foundation, version 3.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU Lesser General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* 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/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.seibel.lod.common.wrappers;
|
package com.seibel.lod.common.wrappers;
|
||||||
|
|
||||||
import java.nio.FloatBuffer;
|
import java.nio.FloatBuffer;
|
||||||
|
import java.util.function.BiConsumer;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
import com.mojang.math.Matrix4f;
|
import com.mojang.math.Matrix4f;
|
||||||
import com.seibel.lod.common.wrappers.block.BlockPosWrapper;
|
import com.seibel.lod.core.enums.ELodDirection;
|
||||||
import com.seibel.lod.core.enums.LodDirection;
|
import com.seibel.lod.core.pos.DhBlockPos;
|
||||||
import com.seibel.lod.core.objects.math.Mat4f;
|
import com.seibel.lod.core.pos.DhChunkPos;
|
||||||
import com.seibel.lod.core.wrapperInterfaces.block.AbstractBlockPosWrapper;
|
import com.seibel.lod.core.util.math.Mat4f;
|
||||||
|
|
||||||
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.ChunkPos;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class converts to and from Minecraft objects (Ex: Matrix4f)
|
* This class converts to and from Minecraft objects (Ex: Matrix4f)
|
||||||
@@ -51,29 +54,60 @@ public class McObjectConverter
|
|||||||
|
|
||||||
|
|
||||||
static final Direction[] directions;
|
static final Direction[] directions;
|
||||||
static final LodDirection[] lodDirections;
|
static final ELodDirection[] lodDirections;
|
||||||
static {
|
static {
|
||||||
LodDirection[] lodDirs = LodDirection.values();
|
ELodDirection[] lodDirs = ELodDirection.values();
|
||||||
directions = new Direction[lodDirs.length];
|
directions = new Direction[lodDirs.length];
|
||||||
lodDirections = new LodDirection[lodDirs.length];
|
lodDirections = new ELodDirection[lodDirs.length];
|
||||||
for (LodDirection lodDir : lodDirs) {
|
for (ELodDirection lodDir : lodDirs) {
|
||||||
Direction dir = Direction.byName(lodDir.name());
|
Direction dir = switch (lodDir.name().toUpperCase()) {
|
||||||
directions[lodDir.ordinal()] = dir;
|
case "DOWN" -> Direction.DOWN;
|
||||||
|
case "UP" -> Direction.UP;
|
||||||
|
case "NORTH" -> Direction.NORTH;
|
||||||
|
case "SOUTH" -> Direction.SOUTH;
|
||||||
|
case "WEST" -> Direction.WEST;
|
||||||
|
case "EAST" -> Direction.EAST;
|
||||||
|
default -> null;
|
||||||
|
};
|
||||||
|
if (dir == null) {
|
||||||
|
throw new IllegalArgumentException("Invalid direction on init mapping: " + lodDir);
|
||||||
|
}
|
||||||
|
directions[lodDir.ordinal()] = dir;
|
||||||
lodDirections[dir.ordinal()] = lodDir;
|
lodDirections[dir.ordinal()] = lodDir;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static BlockPos Convert(AbstractBlockPosWrapper wrappedPos) {
|
public static BlockPos Convert(DhBlockPos wrappedPos) {
|
||||||
return new BlockPos(wrappedPos.getX(),wrappedPos.getY(), wrappedPos.getZ());
|
return new BlockPos(wrappedPos.x, wrappedPos.y, wrappedPos.z);
|
||||||
}
|
}
|
||||||
|
public static ChunkPos Convert(DhChunkPos wrappedPos) {
|
||||||
|
return new ChunkPos(wrappedPos.x, wrappedPos.z);
|
||||||
public static Direction Convert(LodDirection lodDirection)
|
}
|
||||||
|
|
||||||
|
public static Direction Convert(ELodDirection lodDirection)
|
||||||
{
|
{
|
||||||
return directions[lodDirection.ordinal()];
|
return directions[lodDirection.ordinal()];
|
||||||
}
|
}
|
||||||
public static LodDirection Convert(Direction direction)
|
public static ELodDirection Convert(Direction direction)
|
||||||
{
|
{
|
||||||
return lodDirections[direction.ordinal()];
|
return lodDirections[direction.ordinal()];
|
||||||
}
|
}
|
||||||
|
public static void DebugCheckAllPackers() {
|
||||||
|
BiConsumer<Integer, Integer> func = (x, z) -> DhChunkPos._DebugCheckPacker(x,z,ChunkPos.asLong(x,z));
|
||||||
|
func.accept(0,0);
|
||||||
|
func.accept(12345,134);
|
||||||
|
func.accept(-12345,-134);
|
||||||
|
func.accept(-30000000/16,30000000/16);
|
||||||
|
func.accept(30000000/16,-30000000/16);
|
||||||
|
func.accept(30000000/16,30000000/16);
|
||||||
|
func.accept(-30000000/16,-30000000/16);
|
||||||
|
Consumer<BlockPos> func2 = (p) -> DhBlockPos._DebugCheckPacker(p.getX(),p.getY(),p.getZ(),p.asLong());
|
||||||
|
func2.accept(new BlockPos(0,0,0));
|
||||||
|
func2.accept(new BlockPos(12345,134,123));
|
||||||
|
func2.accept(new BlockPos(-12345,-134,-80));
|
||||||
|
func2.accept(new BlockPos(-30000000, 2047, 30000000));
|
||||||
|
func2.accept(new BlockPos(30000000, -2048, -30000000));
|
||||||
|
func2.accept(new BlockPos(30000000, 2047, 30000000));
|
||||||
|
func2.accept(new BlockPos(-30000000, -2048, -30000000));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,26 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
|
||||||
|
* licensed under the GNU LGPL v3 License.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2020-2022 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.lod.common.wrappers;
|
package com.seibel.lod.common.wrappers;
|
||||||
|
|
||||||
import com.seibel.lod.core.enums.config.DistanceGenerationMode;
|
|
||||||
import com.seibel.lod.core.wrapperInterfaces.IVersionConstants;
|
import com.seibel.lod.core.wrapperInterfaces.IVersionConstants;
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author James Seibel
|
* @author James Seibel
|
||||||
@@ -36,4 +54,9 @@ public class VersionConstants implements IVersionConstants
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getMinecraftVersion() {
|
||||||
|
return Minecraft.getInstance().getGame().getVersion().getId();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,94 +1,146 @@
|
|||||||
/*
|
/*
|
||||||
* This file is part of the Distant Horizon mod (formerly the LOD Mod),
|
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
|
||||||
* licensed under the GNU GPL v3 License.
|
* licensed under the GNU LGPL v3 License.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2020 James Seibel
|
* Copyright (C) 2020-2022 James Seibel
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
* the Free Software Foundation, version 3.
|
* the Free Software Foundation, version 3.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU Lesser General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* 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/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.seibel.lod.common.wrappers;
|
package com.seibel.lod.common.wrappers;
|
||||||
|
|
||||||
import com.seibel.lod.core.builders.lodBuilding.LodBuilder;
|
import com.seibel.lod.api.interfaces.override.worldGenerator.IDhApiWorldGenerator;
|
||||||
import com.seibel.lod.core.objects.lod.LodDimension;
|
import com.seibel.lod.common.wrappers.block.BlockStateWrapper;
|
||||||
|
import com.seibel.lod.common.wrappers.block.BiomeWrapper;
|
||||||
|
import com.seibel.lod.common.wrappers.chunk.ChunkWrapper;
|
||||||
|
import com.seibel.lod.core.level.IDhLevel;
|
||||||
|
import com.seibel.lod.core.level.IDhServerLevel;
|
||||||
import com.seibel.lod.core.wrapperInterfaces.IWrapperFactory;
|
import com.seibel.lod.core.wrapperInterfaces.IWrapperFactory;
|
||||||
import com.seibel.lod.core.wrapperInterfaces.block.AbstractBlockPosWrapper;
|
import com.seibel.lod.core.wrapperInterfaces.block.IBlockStateWrapper;
|
||||||
import com.seibel.lod.core.wrapperInterfaces.chunk.AbstractChunkPosWrapper;
|
import com.seibel.lod.core.wrapperInterfaces.chunk.IChunkWrapper;
|
||||||
import com.seibel.lod.core.wrapperInterfaces.world.IWorldWrapper;
|
import com.seibel.lod.core.wrapperInterfaces.world.IBiomeWrapper;
|
||||||
import com.seibel.lod.core.wrapperInterfaces.worldGeneration.AbstractBatchGenerationEnvionmentWrapper;
|
import com.seibel.lod.core.wrapperInterfaces.worldGeneration.AbstractBatchGenerationEnvionmentWrapper;
|
||||||
import com.seibel.lod.common.wrappers.block.BlockPosWrapper;
|
|
||||||
import com.seibel.lod.common.wrappers.chunk.ChunkPosWrapper;
|
|
||||||
import com.seibel.lod.common.wrappers.worldGeneration.BatchGenerationEnvironment;
|
import com.seibel.lod.common.wrappers.worldGeneration.BatchGenerationEnvironment;
|
||||||
|
import net.minecraft.world.level.LevelReader;
|
||||||
|
import net.minecraft.world.level.chunk.ChunkAccess;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This handles creating abstract wrapper objects.
|
* This handles creating abstract wrapper objects.
|
||||||
*
|
|
||||||
* @author James Seibel
|
* @author James Seibel
|
||||||
* @version 11-20-2021
|
* @version 2022-12-5
|
||||||
*/
|
*/
|
||||||
public class WrapperFactory implements IWrapperFactory
|
public class WrapperFactory implements IWrapperFactory
|
||||||
{
|
{
|
||||||
public static final WrapperFactory INSTANCE = new WrapperFactory();
|
public static final WrapperFactory INSTANCE = new WrapperFactory();
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AbstractBlockPosWrapper createBlockPos()
|
|
||||||
{
|
|
||||||
return new BlockPosWrapper();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AbstractBlockPosWrapper createBlockPos(int x, int y, int z)
|
|
||||||
{
|
|
||||||
return new BlockPosWrapper(x, y, z);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AbstractChunkPosWrapper createChunkPos()
|
public AbstractBatchGenerationEnvionmentWrapper createBatchGenerator(IDhLevel targetLevel)
|
||||||
{
|
{
|
||||||
return new ChunkPosWrapper();
|
if (targetLevel instanceof IDhServerLevel)
|
||||||
|
{
|
||||||
|
return new BatchGenerationEnvironment((IDhServerLevel) targetLevel);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new IllegalArgumentException("The target level must be a server-side level.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AbstractChunkPosWrapper createChunkPos(long xAndZPositionCombined)
|
public IBiomeWrapper deserializeBiomeWrapper(String str) throws IOException { return BiomeWrapper.deserialize(str); }
|
||||||
{
|
|
||||||
return new ChunkPosWrapper(xAndZPositionCombined);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AbstractChunkPosWrapper createChunkPos(int x, int z)
|
public IBlockStateWrapper deserializeBlockStateWrapper(String str) throws IOException { return BlockStateWrapper.deserialize(str); }
|
||||||
{
|
|
||||||
return new ChunkPosWrapper(x, z);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AbstractChunkPosWrapper createChunkPos(AbstractChunkPosWrapper newChunkPos)
|
public IBlockStateWrapper getAirBlockStateWrapper() { return BlockStateWrapper.AIR; }
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Note: when this is updated for different MC versions, make sure you also update the documentation in
|
||||||
|
* {@link IDhApiWorldGenerator#generateChunks} and the type list in {@link WrapperFactory#createChunkWrapperErrorMessage}. <br><br>
|
||||||
|
*
|
||||||
|
* For full method documentation please see: {@link IWrapperFactory#createChunkWrapper}
|
||||||
|
* @see IWrapperFactory#createChunkWrapper
|
||||||
|
*/
|
||||||
|
public IChunkWrapper createChunkWrapper(Object[] objectArray) throws ClassCastException
|
||||||
{
|
{
|
||||||
return new ChunkPosWrapper(newChunkPos);
|
if (objectArray.length == 1 && objectArray[0] instanceof IChunkWrapper) // alternate option if "instanceof" can't be compiled down to older JRE versions "IChunkWrapper.class.isInstance(objectArray[0])" Feel free to delete this comment if we've compiled the mod for 1.16 or earlier - James
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// this path should only happen when called by Distant Horizons code
|
||||||
|
// API implementors should never hit this path
|
||||||
|
return (IChunkWrapper) objectArray[0];
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
throw new ClassCastException(createChunkWrapperErrorMessage(objectArray));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// correct number of parameters from the API
|
||||||
|
else if (objectArray.length == 2)
|
||||||
|
{
|
||||||
|
// chunk
|
||||||
|
if (!(objectArray[0] instanceof ChunkAccess chunk))
|
||||||
|
{
|
||||||
|
throw new ClassCastException(createChunkWrapperErrorMessage(objectArray));
|
||||||
|
}
|
||||||
|
|
||||||
|
// light source
|
||||||
|
if (!(objectArray[1] instanceof LevelReader lightSource))
|
||||||
|
{
|
||||||
|
throw new ClassCastException(createChunkWrapperErrorMessage(objectArray));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return new ChunkWrapper(chunk, lightSource, /*A DH wrapped level isn't necessary*/null);
|
||||||
|
}
|
||||||
|
// incorrect number of parameters from the API
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new ClassCastException(createChunkWrapperErrorMessage(objectArray));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/** Note: when this is updated for different MC versions, make sure you also update the documentation in {@link IDhApiWorldGenerator#generateChunks}. */
|
||||||
|
private static String createChunkWrapperErrorMessage(Object[] objectArray)
|
||||||
|
{
|
||||||
|
StringBuilder message = new StringBuilder(
|
||||||
|
"Chunk wrapper creation failed. \n" +
|
||||||
|
"Expected parameters: " +
|
||||||
|
"[" + ChunkAccess.class.getName() + "], " +
|
||||||
|
"[" + LevelReader.class.getName() + "]. \n");
|
||||||
|
|
||||||
|
if (objectArray.length != 0)
|
||||||
|
{
|
||||||
|
message.append("Given parameters: ");
|
||||||
|
for (Object obj : objectArray)
|
||||||
|
{
|
||||||
|
message.append("[").append(obj.getClass().getName()).append("], ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
message.append(" No parameters given.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return message.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public AbstractChunkPosWrapper createChunkPos(AbstractBlockPosWrapper blockPos)
|
|
||||||
{
|
|
||||||
return new ChunkPosWrapper(blockPos);
|
|
||||||
}
|
|
||||||
|
|
||||||
public AbstractBatchGenerationEnvionmentWrapper createBatchGenerator(LodBuilder newLodBuilder,
|
|
||||||
LodDimension newLodDimension, IWorldWrapper worldWrapper)
|
|
||||||
{
|
|
||||||
return new BatchGenerationEnvironment(worldWrapper, newLodBuilder, newLodDimension);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,19 +1,19 @@
|
|||||||
/*
|
/*
|
||||||
* This file is part of the Distant Horizon mod (formerly the LOD Mod),
|
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
|
||||||
* licensed under the GNU GPL v3 License.
|
* licensed under the GNU LGPL v3 License.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2020 James Seibel
|
* Copyright (C) 2020-2022 James Seibel
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
* the Free Software Foundation, version 3.
|
* the Free Software Foundation, version 3.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU Lesser General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* 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/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,114 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
|
||||||
|
* licensed under the GNU LGPL v3 License.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2020-2022 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.lod.common.wrappers.block;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.concurrent.ConcurrentMap;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableBiMap;
|
||||||
|
import com.google.gson.JsonParser;
|
||||||
|
import com.mojang.serialization.JsonOps;
|
||||||
|
import com.mojang.serialization.Lifecycle;
|
||||||
|
import com.seibel.lod.core.wrapperInterfaces.world.IBiomeWrapper;
|
||||||
|
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.core.Holder;
|
||||||
|
#if POST_MC_1_19
|
||||||
|
import net.minecraft.data.worldgen.biome.EndBiomes;
|
||||||
|
import net.minecraft.data.worldgen.biome.NetherBiomes;
|
||||||
|
#endif
|
||||||
|
import net.minecraft.resources.RegistryFixedCodec;
|
||||||
|
import net.minecraft.resources.RegistryOps;
|
||||||
|
import net.minecraft.world.level.biome.Biome;
|
||||||
|
import net.minecraft.world.level.biome.Biomes;
|
||||||
|
|
||||||
|
|
||||||
|
/** This class wraps the minecraft BlockPos.Mutable (and BlockPos) class */
|
||||||
|
public class BiomeWrapper implements IBiomeWrapper
|
||||||
|
{
|
||||||
|
#if PRE_MC_1_18_2
|
||||||
|
public static final ConcurrentMap<Biome, BiomeWrapper> biomeWrapperMap = new ConcurrentHashMap<>();
|
||||||
|
public final Biome biome;
|
||||||
|
#else
|
||||||
|
public static final ConcurrentMap<Holder<Biome>, BiomeWrapper> biomeWrapperMap = new ConcurrentHashMap<>();
|
||||||
|
public final Holder<Biome> biome;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static public IBiomeWrapper getBiomeWrapper(#if PRE_MC_1_18_2 Biome #else Holder<Biome> #endif biome)
|
||||||
|
{
|
||||||
|
return biomeWrapperMap.computeIfAbsent(biome, BiomeWrapper::new);
|
||||||
|
}
|
||||||
|
|
||||||
|
private BiomeWrapper(#if PRE_MC_1_18_2 Biome #else Holder<Biome> #endif biome)
|
||||||
|
{
|
||||||
|
this.biome = biome;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName()
|
||||||
|
{
|
||||||
|
#if PRE_MC_1_18_2
|
||||||
|
return biome.toString();
|
||||||
|
#else
|
||||||
|
return biome.unwrapKey().orElse(Biomes.THE_VOID).registry().toString();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String serialize() {
|
||||||
|
//FIXME: Pass in a level obj
|
||||||
|
String data = Biome.CODEC.encodeStart(RegistryOps.create(JsonOps.INSTANCE, Minecraft.getInstance().level.registryAccess()),
|
||||||
|
biome).get().orThrow().toString();
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
BiomeWrapper that = (BiomeWrapper) o;
|
||||||
|
return Objects.equals(biome, that.biome);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(biome);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IBiomeWrapper deserialize(String str) throws IOException {
|
||||||
|
try {
|
||||||
|
#if PRE_MC_1_18_2 Biome #else
|
||||||
|
Holder<Biome> #endif
|
||||||
|
biome = Biome.CODEC.decode(RegistryOps.create(JsonOps.INSTANCE, Minecraft.getInstance().level.registryAccess()),
|
||||||
|
JsonParser.parseString(str)).get().orThrow().getFirst();
|
||||||
|
return getBiomeWrapper(biome);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new IOException("Failed to deserialize biome wrapper", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getWrappedMcObject_UNSAFE() { return this.biome; }
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
package com.seibel.lod.common.wrappers.block;
|
|
||||||
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
|
||||||
|
|
||||||
import net.minecraft.core.BlockPos;
|
|
||||||
import net.minecraft.world.level.LevelReader;
|
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
|
||||||
|
|
||||||
public class BlockDetailMap
|
|
||||||
{
|
|
||||||
|
|
||||||
private static ConcurrentHashMap<BlockState, BlockDetailWrapper> map = new ConcurrentHashMap<BlockState, BlockDetailWrapper>();
|
|
||||||
|
|
||||||
private BlockDetailMap() {}
|
|
||||||
|
|
||||||
public static BlockDetailWrapper getOrMakeBlockDetailCache(BlockState bs, BlockPos pos, LevelReader getter) {
|
|
||||||
BlockDetailWrapper cache = map.get(bs);
|
|
||||||
if (cache != null) return cache;
|
|
||||||
if (bs.getFluidState().isEmpty()) {
|
|
||||||
cache = BlockDetailWrapper.make(bs, pos, getter);
|
|
||||||
} else {
|
|
||||||
cache = BlockDetailWrapper.make(bs.getFluidState().createLegacyBlock(), pos, getter);
|
|
||||||
}
|
|
||||||
BlockDetailWrapper cacheCAS = map.putIfAbsent(bs, cache);
|
|
||||||
return cacheCAS==null ? cache : cacheCAS;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,315 +0,0 @@
|
|||||||
package com.seibel.lod.common.wrappers.block;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.Random;
|
|
||||||
import java.util.function.BiFunction;
|
|
||||||
import java.util.function.Function;
|
|
||||||
import java.util.function.Supplier;
|
|
||||||
import java.util.stream.Stream;
|
|
||||||
|
|
||||||
import com.seibel.lod.common.Config;
|
|
||||||
import com.seibel.lod.common.wrappers.McObjectConverter;
|
|
||||||
import com.seibel.lod.common.wrappers.chunk.ChunkWrapper;
|
|
||||||
import com.seibel.lod.core.api.ApiShared;
|
|
||||||
import com.seibel.lod.core.enums.LodDirection;
|
|
||||||
import com.seibel.lod.core.handlers.dependencyInjection.SingletonHandler;
|
|
||||||
import com.seibel.lod.core.util.ColorUtil;
|
|
||||||
import com.seibel.lod.core.wrapperInterfaces.block.AbstractBlockPosWrapper;
|
|
||||||
import com.seibel.lod.core.wrapperInterfaces.block.IBlockDetailWrapper;
|
|
||||||
import com.seibel.lod.core.wrapperInterfaces.chunk.IChunkWrapper;
|
|
||||||
|
|
||||||
import com.seibel.lod.core.wrapperInterfaces.config.ILodConfigWrapperSingleton;
|
|
||||||
import it.unimi.dsi.fastutil.objects.Object2ObjectArrayMap;
|
|
||||||
import net.minecraft.Util;
|
|
||||||
import net.minecraft.client.Minecraft;
|
|
||||||
import net.minecraft.client.color.block.BlockTintCache;
|
|
||||||
import net.minecraft.client.renderer.BiomeColors;
|
|
||||||
import net.minecraft.client.renderer.block.model.BakedQuad;
|
|
||||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
|
||||||
import net.minecraft.core.BlockPos;
|
|
||||||
import net.minecraft.core.Cursor3D;
|
|
||||||
import net.minecraft.core.Direction;
|
|
||||||
import net.minecraft.world.level.*;
|
|
||||||
import net.minecraft.world.level.biome.Biome;
|
|
||||||
import net.minecraft.world.level.block.Block;
|
|
||||||
import net.minecraft.world.level.block.Blocks;
|
|
||||||
import net.minecraft.world.level.block.FlowerBlock;
|
|
||||||
import net.minecraft.world.level.block.LeavesBlock;
|
|
||||||
import net.minecraft.world.level.block.RenderShape;
|
|
||||||
import net.minecraft.world.level.block.RotatedPillarBlock;
|
|
||||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
|
||||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
|
||||||
import net.minecraft.world.level.lighting.LevelLightEngine;
|
|
||||||
import net.minecraft.world.level.material.FluidState;
|
|
||||||
import net.minecraft.world.phys.AABB;
|
|
||||||
import net.minecraft.world.phys.BlockHitResult;
|
|
||||||
import net.minecraft.world.phys.Vec3;
|
|
||||||
import net.minecraft.world.phys.shapes.VoxelShape;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
public class BlockDetailWrapper extends IBlockDetailWrapper
|
|
||||||
{
|
|
||||||
private static final ILodConfigWrapperSingleton CONFIG = SingletonHandler.get(ILodConfigWrapperSingleton.class);
|
|
||||||
|
|
||||||
public static final int FLOWER_COLOR_SCALE = 5;
|
|
||||||
|
|
||||||
public static final Random random = new Random(0);
|
|
||||||
|
|
||||||
enum ColorMode {
|
|
||||||
Default,
|
|
||||||
Flower,
|
|
||||||
Leaves;
|
|
||||||
static ColorMode getColorMode(Block b) {
|
|
||||||
if (b instanceof LeavesBlock) return Leaves;
|
|
||||||
if (b instanceof FlowerBlock) return Flower;
|
|
||||||
return Default;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//TODO: Perhaps make this not just use the first frame?
|
|
||||||
private static int calculateColorFromTexture(TextureAtlasSprite texture, ColorMode colorMode) {
|
|
||||||
|
|
||||||
int count = 0;
|
|
||||||
double alpha = 0;
|
|
||||||
double red = 0;
|
|
||||||
double green = 0;
|
|
||||||
double blue = 0;
|
|
||||||
int tempColor;
|
|
||||||
|
|
||||||
{
|
|
||||||
// textures normally use u and v instead of x and y
|
|
||||||
for (int u = 0; u < texture.getWidth(); u++)
|
|
||||||
{
|
|
||||||
for (int v = 0; v < texture.getHeight(); v++)
|
|
||||||
{
|
|
||||||
//note: Minecraft color format is: 0xAA BB GG RR
|
|
||||||
//________ DH mod color format is: 0xAA RR GG BB
|
|
||||||
//OpenGL RGBA format native order: 0xRR GG BB AA
|
|
||||||
//_ OpenGL RGBA format Java Order: 0xAA BB GG RR
|
|
||||||
tempColor = TextureAtlasSpriteWrapper.getPixelRGBA(texture, 0, u, v);
|
|
||||||
|
|
||||||
double r = ((tempColor & 0x000000FF) )/255.;
|
|
||||||
double g = ((tempColor & 0x0000FF00) >>> 8)/255.;
|
|
||||||
double b = ((tempColor & 0x00FF0000) >>> 16)/255.;
|
|
||||||
double a = ((tempColor & 0xFF000000) >>> 24)/255.;
|
|
||||||
int scale = 1;
|
|
||||||
|
|
||||||
if (colorMode == ColorMode.Leaves) {
|
|
||||||
r *= a;
|
|
||||||
g *= a;
|
|
||||||
b *= a;
|
|
||||||
a = 1.;
|
|
||||||
} else if (a==0.) {
|
|
||||||
continue;
|
|
||||||
} else if (colorMode == ColorMode.Flower && (g+0.1<b || g+0.1<r)) {
|
|
||||||
scale = FLOWER_COLOR_SCALE;
|
|
||||||
}
|
|
||||||
|
|
||||||
count += scale;
|
|
||||||
alpha += a*a*scale;
|
|
||||||
red += r*r*scale;
|
|
||||||
green += g*g*scale;
|
|
||||||
blue += b*b*scale;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (count == 0)
|
|
||||||
// this block is entirely transparent
|
|
||||||
tempColor = ColorUtil.rgbToInt(255,255,0,255);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// determine the average color
|
|
||||||
tempColor = ColorUtil.rgbToInt(
|
|
||||||
(int) (Math.sqrt(alpha/count)*255.),
|
|
||||||
(int) (Math.sqrt(red / count)*255.),
|
|
||||||
(int) (Math.sqrt(green / count)*255.),
|
|
||||||
(int) (Math.sqrt(blue / count)*255.));
|
|
||||||
}
|
|
||||||
// TODO: Remove this when transparency is added!
|
|
||||||
double colorAlpha = ColorUtil.getAlpha(tempColor)/255.;
|
|
||||||
tempColor = ColorUtil.rgbToInt(
|
|
||||||
ColorUtil.getAlpha(tempColor),
|
|
||||||
(int)(ColorUtil.getRed(tempColor) * colorAlpha),
|
|
||||||
(int)(ColorUtil.getGreen(tempColor) * colorAlpha),
|
|
||||||
(int)(ColorUtil.getBlue(tempColor) * colorAlpha)
|
|
||||||
);
|
|
||||||
return tempColor;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private static final Block[] BLOCK_TO_AVOID = {Blocks.AIR, Blocks.CAVE_AIR, Blocks.BARRIER};
|
|
||||||
|
|
||||||
private static final Direction[] DIRECTION_ORDER = {Direction.UP, Direction.NORTH, Direction.EAST, Direction.WEST, Direction.SOUTH, Direction.DOWN};
|
|
||||||
|
|
||||||
private static boolean isBlockToBeAvoid(Block b) {
|
|
||||||
for (Block bta : BLOCK_TO_AVOID)
|
|
||||||
if (bta==b) return true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
final BlockState state;
|
|
||||||
final BlockPos samplePos;
|
|
||||||
final LevelReader sampleGetter;
|
|
||||||
|
|
||||||
boolean isShapeResolved = false;
|
|
||||||
boolean[] dontOccludeFaces = null;
|
|
||||||
boolean noCollision = false;
|
|
||||||
boolean noFullFace = false;
|
|
||||||
|
|
||||||
boolean isColorResolved = false;
|
|
||||||
int baseColor = 0; //TODO: Impl per-face color
|
|
||||||
boolean needShade = true;
|
|
||||||
boolean needPostTinting = false;
|
|
||||||
int tintIndex = 0;
|
|
||||||
|
|
||||||
public static BlockDetailWrapper NULL_BLOCK_DETAIL = new BlockDetailWrapper();
|
|
||||||
|
|
||||||
public BlockDetailWrapper(BlockState state, BlockPos pos, LevelReader getter) {
|
|
||||||
this.state = state;
|
|
||||||
this.samplePos = pos;
|
|
||||||
this.sampleGetter = getter;
|
|
||||||
}
|
|
||||||
|
|
||||||
private BlockDetailWrapper() {
|
|
||||||
this.state = null;
|
|
||||||
this.samplePos = null;
|
|
||||||
this.sampleGetter = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
static BlockDetailWrapper make(BlockState bs, BlockPos pos, LevelReader getter) {
|
|
||||||
if(!bs.getFluidState().isEmpty()) { // Is a fluidBlock
|
|
||||||
if (isBlockToBeAvoid(bs.getBlock())) return NULL_BLOCK_DETAIL;
|
|
||||||
if (bs.isAir()) return NULL_BLOCK_DETAIL;
|
|
||||||
return new BlockDetailWrapper(bs, pos, getter);
|
|
||||||
} else {
|
|
||||||
if (bs.getRenderShape() != RenderShape.MODEL) return NULL_BLOCK_DETAIL;
|
|
||||||
if (isBlockToBeAvoid(bs.getBlock())) return NULL_BLOCK_DETAIL;
|
|
||||||
return new BlockDetailWrapper(bs, pos, getter);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void resolveShapes() {
|
|
||||||
if (isShapeResolved) return;
|
|
||||||
if (state.getFluidState().isEmpty()) {
|
|
||||||
noCollision = state.getCollisionShape(sampleGetter, samplePos).isEmpty();
|
|
||||||
dontOccludeFaces = new boolean[6];
|
|
||||||
if (state.canOcclude()) {
|
|
||||||
/* FIXME: Figure out how or if needed to impl per-face culling?
|
|
||||||
for (Direction dir : Direction.values()) {
|
|
||||||
dontOccludeFaces[McObjectConverter.Convert(dir).ordinal()]
|
|
||||||
= state.getFaceOcclusionShape(sampleGetter, samplePos, dir).isEmpty();
|
|
||||||
}*/
|
|
||||||
} else {
|
|
||||||
Arrays.fill(dontOccludeFaces, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
VoxelShape voxelShape = state.getShape(sampleGetter, samplePos);
|
|
||||||
if (voxelShape.isEmpty()) {
|
|
||||||
noFullFace = true;
|
|
||||||
} else {
|
|
||||||
AABB bbox = voxelShape.bounds();
|
|
||||||
double xWidth = (bbox.maxX - bbox.minX);
|
|
||||||
double yWidth = (bbox.maxY - bbox.minY);
|
|
||||||
double zWidth = (bbox.maxZ - bbox.minZ);
|
|
||||||
noFullFace = xWidth < 1 && zWidth < 1 && yWidth < 1;
|
|
||||||
}
|
|
||||||
} else { // Liquid Block
|
|
||||||
dontOccludeFaces = new boolean[6];
|
|
||||||
}
|
|
||||||
isShapeResolved = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void resolveColors() {
|
|
||||||
if (isColorResolved) return;
|
|
||||||
if (state.getFluidState().isEmpty()) {
|
|
||||||
List<BakedQuad> quads = null;
|
|
||||||
for (Direction direction : DIRECTION_ORDER)
|
|
||||||
{
|
|
||||||
quads = Minecraft.getInstance().getModelManager().getBlockModelShaper().
|
|
||||||
getBlockModel(state).getQuads(state, direction, random);
|
|
||||||
if (!quads.isEmpty() &&
|
|
||||||
!(state.getBlock() instanceof RotatedPillarBlock && direction == Direction.UP))
|
|
||||||
break;
|
|
||||||
};
|
|
||||||
if (quads != null && !quads.isEmpty()) {
|
|
||||||
needPostTinting = quads.get(0).isTinted();
|
|
||||||
needShade = quads.get(0).isShade();
|
|
||||||
tintIndex = quads.get(0).getTintIndex();
|
|
||||||
baseColor = calculateColorFromTexture(quads.get(0).getSprite(),
|
|
||||||
ColorMode.getColorMode(state.getBlock()));
|
|
||||||
}
|
|
||||||
} else { // Liquid Block
|
|
||||||
|
|
||||||
needPostTinting = true;
|
|
||||||
needShade = false;
|
|
||||||
tintIndex = 0;
|
|
||||||
baseColor = calculateColorFromTexture(Minecraft.getInstance().getModelManager().getBlockModelShaper().getParticleIcon(state),
|
|
||||||
ColorMode.getColorMode(state.getBlock()));
|
|
||||||
|
|
||||||
}
|
|
||||||
isColorResolved = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private BlockAndTintGetter wrapColorResolver(LevelReader level) {
|
|
||||||
int blendDistance = CONFIG.client().graphics().quality().getLodBiomeBlending();
|
|
||||||
if (blendDistance == 0) {
|
|
||||||
return new TintGetterOverrideFast(level);
|
|
||||||
} else {
|
|
||||||
return new TintGetterOverrideSmooth(level, blendDistance);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getAndResolveFaceColor(LodDirection dir, IChunkWrapper chunk, AbstractBlockPosWrapper blockPos)
|
|
||||||
{
|
|
||||||
// FIXME: impl per-face colors
|
|
||||||
resolveColors();
|
|
||||||
if (!needPostTinting) return baseColor;
|
|
||||||
int tintColor = Minecraft.getInstance().getBlockColors()
|
|
||||||
.getColor(state, wrapColorResolver(((ChunkWrapper)chunk).getColorResolver()),
|
|
||||||
McObjectConverter.Convert(blockPos), tintIndex);
|
|
||||||
if (tintColor == -1) return baseColor;
|
|
||||||
return ColorUtil.multiplyARGBwithRGB(baseColor, tintColor);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean hasFaceCullingFor(LodDirection dir)
|
|
||||||
{
|
|
||||||
resolveShapes();
|
|
||||||
return !dontOccludeFaces[dir.ordinal()];
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean hasNoCollision()
|
|
||||||
{
|
|
||||||
resolveShapes();
|
|
||||||
return noCollision;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean noFaceIsFullFace()
|
|
||||||
{
|
|
||||||
resolveShapes();
|
|
||||||
return noFullFace;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String serialize()
|
|
||||||
{
|
|
||||||
// FIXME: Impl this for the blockState Storage stuff
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean isSame(IBlockDetailWrapper iBlockDetail)
|
|
||||||
{
|
|
||||||
return ((BlockDetailWrapper)iBlockDetail).state.getBlock().equals(state.getBlock());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,84 +0,0 @@
|
|||||||
package com.seibel.lod.common.wrappers.block;
|
|
||||||
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
import com.seibel.lod.core.enums.LodDirection;
|
|
||||||
import com.seibel.lod.core.wrapperInterfaces.block.AbstractBlockPosWrapper;
|
|
||||||
|
|
||||||
import net.minecraft.core.BlockPos;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author James Seibel
|
|
||||||
* @version 11-21-2021
|
|
||||||
*/
|
|
||||||
public class BlockPosWrapper extends AbstractBlockPosWrapper
|
|
||||||
{
|
|
||||||
private final BlockPos.MutableBlockPos blockPos;
|
|
||||||
|
|
||||||
|
|
||||||
public BlockPosWrapper()
|
|
||||||
{
|
|
||||||
this.blockPos = new BlockPos.MutableBlockPos(0,0,0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public BlockPosWrapper(int x, int y, int z)
|
|
||||||
{
|
|
||||||
this.blockPos = new BlockPos.MutableBlockPos(x, y, z);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void set(int x, int y, int z)
|
|
||||||
{
|
|
||||||
blockPos.set(x, y, z);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getX()
|
|
||||||
{
|
|
||||||
return blockPos.getX();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getY()
|
|
||||||
{
|
|
||||||
return blockPos.getY();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getZ()
|
|
||||||
{
|
|
||||||
return blockPos.getZ();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int get(LodDirection.Axis axis)
|
|
||||||
{
|
|
||||||
return axis.choose(getX(), getY(), getZ());
|
|
||||||
}
|
|
||||||
|
|
||||||
public BlockPos.MutableBlockPos getBlockPos()
|
|
||||||
{
|
|
||||||
return blockPos;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public boolean equals(Object o)
|
|
||||||
{
|
|
||||||
return blockPos.equals(o);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public int hashCode()
|
|
||||||
{
|
|
||||||
return Objects.hash(blockPos);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BlockPosWrapper offset(int x, int y, int z)
|
|
||||||
{
|
|
||||||
blockPos.set(blockPos.getX() + x, blockPos.getY() + y, blockPos.getZ() + z);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,87 @@
|
|||||||
|
package com.seibel.lod.common.wrappers.block;
|
||||||
|
|
||||||
|
import com.google.gson.JsonParser;
|
||||||
|
import com.mojang.serialization.JsonOps;
|
||||||
|
import com.seibel.lod.core.logging.DhLoggerBuilder;
|
||||||
|
import com.seibel.lod.core.wrapperInterfaces.block.IBlockStateWrapper;
|
||||||
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
public class BlockStateWrapper implements IBlockStateWrapper
|
||||||
|
{
|
||||||
|
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
|
||||||
|
public static final BlockStateWrapper AIR = new BlockStateWrapper(null);
|
||||||
|
|
||||||
|
public static ConcurrentHashMap<BlockState, BlockStateWrapper> cache = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
public static BlockStateWrapper fromBlockState(BlockState blockState)
|
||||||
|
{
|
||||||
|
if (blockState == null || blockState.isAir())
|
||||||
|
return AIR;
|
||||||
|
|
||||||
|
if (blockState.getFluidState().isEmpty())
|
||||||
|
return cache.computeIfAbsent(blockState, BlockStateWrapper::new);
|
||||||
|
else
|
||||||
|
return cache.computeIfAbsent(blockState.getFluidState().createLegacyBlock(), BlockStateWrapper::new);
|
||||||
|
}
|
||||||
|
|
||||||
|
public final BlockState blockState;
|
||||||
|
BlockStateWrapper(BlockState blockState) {
|
||||||
|
this.blockState = blockState;
|
||||||
|
//LOGGER.info("Created BlockStateWrapper for {}", blockState);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String serialize() {
|
||||||
|
if (blockState == null) {
|
||||||
|
return "AIR";
|
||||||
|
}
|
||||||
|
return BlockState.CODEC.encodeStart(JsonOps.COMPRESSED, blockState).get().orThrow().toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static BlockStateWrapper deserialize(String str) throws IOException {
|
||||||
|
if (str.equals("AIR")) {
|
||||||
|
return AIR;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
return new BlockStateWrapper(
|
||||||
|
BlockState.CODEC.decode(JsonOps.COMPRESSED, JsonParser.parseString(str)).get().orThrow().getFirst()
|
||||||
|
);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new IOException("Failed to deserialize BlockStateWrapper", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
BlockStateWrapper that = (BlockStateWrapper) o;
|
||||||
|
return Objects.equals(blockState, that.blockState);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(blockState);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getWrappedMcObject_UNSAFE() { return this.blockState; }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isAir() { return this.isAir(this.blockState); }
|
||||||
|
public boolean isAir(BlockState blockState) { return blockState == null || blockState.isAir(); }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
+25
-1
@@ -1,3 +1,22 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
|
||||||
|
* licensed under the GNU LGPL v3 License.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2020-2022 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.lod.common.wrappers.block;
|
package com.seibel.lod.common.wrappers.block;
|
||||||
|
|
||||||
|
|
||||||
@@ -18,11 +37,16 @@ public class TextureAtlasSpriteWrapper {
|
|||||||
* The code has been modified to use TextureAtlasSprite
|
* The code has been modified to use TextureAtlasSprite
|
||||||
*/
|
*/
|
||||||
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
|
||||||
|
return sprite.mainImage[0].getPixelRGBA(
|
||||||
|
x + sprite.framesX[frameIndex] * sprite.getWidth(),
|
||||||
|
y + sprite.framesY[frameIndex] * sprite.getHeight());
|
||||||
|
#else
|
||||||
if (sprite.animatedTexture != null) {
|
if (sprite.animatedTexture != null) {
|
||||||
x += sprite.animatedTexture.getFrameX(frameIndex) * sprite.width;
|
x += sprite.animatedTexture.getFrameX(frameIndex) * sprite.width;
|
||||||
y += sprite.animatedTexture.getFrameY(frameIndex) * sprite.height;
|
y += sprite.animatedTexture.getFrameY(frameIndex) * sprite.height;
|
||||||
}
|
}
|
||||||
|
|
||||||
return sprite.mainImage[0].getPixelRGBA(x, y);
|
return sprite.mainImage[0].getPixelRGBA(x, y);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+45
-24
@@ -1,5 +1,25 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
|
||||||
|
* licensed under the GNU LGPL v3 License.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2020-2022 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.lod.common.wrappers.block;
|
package com.seibel.lod.common.wrappers.block;
|
||||||
|
|
||||||
|
import com.seibel.lod.common.LodCommonMain;
|
||||||
import it.unimi.dsi.fastutil.objects.Object2ObjectArrayMap;
|
import it.unimi.dsi.fastutil.objects.Object2ObjectArrayMap;
|
||||||
import net.minecraft.Util;
|
import net.minecraft.Util;
|
||||||
import net.minecraft.client.color.block.BlockTintCache;
|
import net.minecraft.client.color.block.BlockTintCache;
|
||||||
@@ -27,29 +47,27 @@ import java.util.stream.Stream;
|
|||||||
|
|
||||||
public class TintGetterOverrideFast implements BlockAndTintGetter {
|
public class TintGetterOverrideFast implements BlockAndTintGetter {
|
||||||
LevelReader parent;
|
LevelReader parent;
|
||||||
private final Object2ObjectArrayMap<ColorResolver, ConcurrentHashMap<Biome, Integer>> tintCaches;
|
|
||||||
|
|
||||||
public TintGetterOverrideFast(LevelReader parent) {
|
public TintGetterOverrideFast(LevelReader parent) {
|
||||||
this.parent = parent;
|
this.parent = parent;
|
||||||
this.tintCaches = Util.make(new Object2ObjectArrayMap(3), object2ObjectArrayMap -> {
|
|
||||||
object2ObjectArrayMap.put(BiomeColors.GRASS_COLOR_RESOLVER, new ConcurrentHashMap<Biome, Integer>());
|
|
||||||
object2ObjectArrayMap.put(BiomeColors.FOLIAGE_COLOR_RESOLVER, new ConcurrentHashMap<Biome, Integer>());
|
|
||||||
object2ObjectArrayMap.put(BiomeColors.WATER_COLOR_RESOLVER, new ConcurrentHashMap<Biome, Integer>());
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Biome _getBiome(BlockPos pos) {
|
private Biome _getBiome(BlockPos pos) {
|
||||||
#if MC_VERSION_1_18_2
|
#if POST_MC_1_18_2
|
||||||
return parent.getBiome(pos).value();
|
return parent.getBiome(pos).value();
|
||||||
#elif MC_VERSION_1_18_1
|
#else
|
||||||
return parent.getBiome(pos);
|
return parent.getBiome(pos);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getBlockTint(BlockPos blockPos, ColorResolver colorResolver) {
|
public int getBlockTint(BlockPos blockPos, ColorResolver colorResolver) {
|
||||||
Biome b = _getBiome(blockPos);
|
if (LodCommonMain.forgeMethodCaller != null) {
|
||||||
return tintCaches.get(colorResolver).computeIfAbsent(b, (key) -> colorResolver.getColor(b, blockPos.getX(), blockPos.getZ()));
|
return LodCommonMain.forgeMethodCaller.colorResolverGetColor(colorResolver, _getBiome(blockPos),
|
||||||
|
blockPos.getX(), blockPos.getZ());
|
||||||
|
} else {
|
||||||
|
return colorResolver.getColor(_getBiome(blockPos), blockPos.getX(), blockPos.getZ());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -83,10 +101,6 @@ public class TintGetterOverrideFast implements BlockAndTintGetter {
|
|||||||
return parent.getBlockEntity(blockPos);
|
return parent.getBlockEntity(blockPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public <T extends BlockEntity> Optional<T> getBlockEntity(BlockPos blockPos, BlockEntityType<T> blockEntityType) {
|
|
||||||
return parent.getBlockEntity(blockPos, blockEntityType);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BlockState getBlockState(BlockPos blockPos) {
|
public BlockState getBlockState(BlockPos blockPos) {
|
||||||
@@ -113,11 +127,6 @@ public class TintGetterOverrideFast implements BlockAndTintGetter {
|
|||||||
return parent.getBlockStates(aABB);
|
return parent.getBlockStates(aABB);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public BlockHitResult isBlockInLine(ClipBlockStateContext clipBlockStateContext) {
|
|
||||||
return parent.isBlockInLine(clipBlockStateContext);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BlockHitResult clip(ClipContext clipContext) {
|
public BlockHitResult clip(ClipContext clipContext) {
|
||||||
return parent.clip(clipContext);
|
return parent.clip(clipContext);
|
||||||
@@ -139,6 +148,22 @@ public class TintGetterOverrideFast implements BlockAndTintGetter {
|
|||||||
return parent.getBlockFloorHeight(blockPos);
|
return parent.getBlockFloorHeight(blockPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMaxBuildHeight() {
|
||||||
|
return parent.getMaxBuildHeight();
|
||||||
|
}
|
||||||
|
|
||||||
|
#if POST_MC_1_17_1
|
||||||
|
@Override
|
||||||
|
public <T extends BlockEntity> Optional<T> getBlockEntity(BlockPos blockPos, BlockEntityType<T> blockEntityType) {
|
||||||
|
return parent.getBlockEntity(blockPos, blockEntityType);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BlockHitResult isBlockInLine(ClipBlockStateContext clipBlockStateContext) {
|
||||||
|
return parent.isBlockInLine(clipBlockStateContext);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getHeight() {
|
public int getHeight() {
|
||||||
return parent.getHeight();
|
return parent.getHeight();
|
||||||
@@ -149,11 +174,6 @@ public class TintGetterOverrideFast implements BlockAndTintGetter {
|
|||||||
return parent.getMinBuildHeight();
|
return parent.getMinBuildHeight();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getMaxBuildHeight() {
|
|
||||||
return parent.getMaxBuildHeight();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getSectionsCount() {
|
public int getSectionsCount() {
|
||||||
return parent.getSectionsCount();
|
return parent.getSectionsCount();
|
||||||
@@ -193,4 +213,5 @@ public class TintGetterOverrideFast implements BlockAndTintGetter {
|
|||||||
public int getSectionYFromSectionIndex(int i) {
|
public int getSectionYFromSectionIndex(int i) {
|
||||||
return parent.getSectionYFromSectionIndex(i);
|
return parent.getSectionYFromSectionIndex(i);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|||||||
+49
-27
@@ -1,5 +1,25 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
|
||||||
|
* licensed under the GNU LGPL v3 License.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2020-2022 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.lod.common.wrappers.block;
|
package com.seibel.lod.common.wrappers.block;
|
||||||
|
|
||||||
|
import com.seibel.lod.common.LodCommonMain;
|
||||||
import it.unimi.dsi.fastutil.objects.Object2ObjectArrayMap;
|
import it.unimi.dsi.fastutil.objects.Object2ObjectArrayMap;
|
||||||
import net.minecraft.Util;
|
import net.minecraft.Util;
|
||||||
import net.minecraft.client.color.block.BlockTintCache;
|
import net.minecraft.client.color.block.BlockTintCache;
|
||||||
@@ -26,24 +46,18 @@ import java.util.stream.Stream;
|
|||||||
|
|
||||||
public class TintGetterOverrideSmooth implements BlockAndTintGetter {
|
public class TintGetterOverrideSmooth implements BlockAndTintGetter {
|
||||||
LevelReader parent;
|
LevelReader parent;
|
||||||
private final Object2ObjectArrayMap<ColorResolver, BlockTintCache> tintCaches;
|
|
||||||
public int smoothingRange;
|
public int smoothingRange;
|
||||||
|
|
||||||
public TintGetterOverrideSmooth(LevelReader parent, int smoothingRange) {
|
public TintGetterOverrideSmooth(LevelReader parent, int smoothingRange) {
|
||||||
this.parent = parent;
|
this.parent = parent;
|
||||||
this.smoothingRange = smoothingRange;
|
this.smoothingRange = smoothingRange;
|
||||||
this.tintCaches = Util.make(new Object2ObjectArrayMap(3), object2ObjectArrayMap -> {
|
|
||||||
object2ObjectArrayMap.put(BiomeColors.GRASS_COLOR_RESOLVER, new BlockTintCache((pos) -> calculateBlockTint(pos, BiomeColors.GRASS_COLOR_RESOLVER)));
|
|
||||||
object2ObjectArrayMap.put(BiomeColors.FOLIAGE_COLOR_RESOLVER, new BlockTintCache((pos) -> calculateBlockTint(pos, BiomeColors.FOLIAGE_COLOR_RESOLVER)));
|
|
||||||
object2ObjectArrayMap.put(BiomeColors.WATER_COLOR_RESOLVER, new BlockTintCache((pos) -> calculateBlockTint(pos, BiomeColors.WATER_COLOR_RESOLVER)));
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Biome _getBiome(BlockPos pos) {
|
private Biome _getBiome(BlockPos pos) {
|
||||||
#if MC_VERSION_1_18_2
|
#if POST_MC_1_18_2
|
||||||
return parent.getBiome(pos).value();
|
return parent.getBiome(pos).value();
|
||||||
#elif MC_VERSION_1_18_1
|
#else
|
||||||
return parent.getBiome(pos);
|
return parent.getBiome(pos);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -61,7 +75,14 @@ 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 = colorResolver.getColor(_getBiome(mutableBlockPos), mutableBlockPos.getX(), mutableBlockPos.getZ());
|
int n;
|
||||||
|
if (LodCommonMain.forgeMethodCaller != null) {
|
||||||
|
n = LodCommonMain.forgeMethodCaller.colorResolverGetColor(colorResolver, _getBiome(mutableBlockPos),
|
||||||
|
mutableBlockPos.getX(), mutableBlockPos.getZ());
|
||||||
|
} else {
|
||||||
|
n = colorResolver.getColor(_getBiome(mutableBlockPos), mutableBlockPos.getX(), mutableBlockPos.getZ());
|
||||||
|
}
|
||||||
|
|
||||||
k += (n & 0xFF0000) >> 16;
|
k += (n & 0xFF0000) >> 16;
|
||||||
l += (n & 0xFF00) >> 8;
|
l += (n & 0xFF00) >> 8;
|
||||||
m += n & 0xFF;
|
m += n & 0xFF;
|
||||||
@@ -71,8 +92,7 @@ public class TintGetterOverrideSmooth implements BlockAndTintGetter {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getBlockTint(BlockPos blockPos, ColorResolver colorResolver) {
|
public int getBlockTint(BlockPos blockPos, ColorResolver colorResolver) {
|
||||||
BlockTintCache blockTintCache = this.tintCaches.get(colorResolver);
|
return calculateBlockTint(blockPos, colorResolver);
|
||||||
return blockTintCache.getColor(blockPos);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -106,11 +126,6 @@ public class TintGetterOverrideSmooth implements BlockAndTintGetter {
|
|||||||
return parent.getBlockEntity(blockPos);
|
return parent.getBlockEntity(blockPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public <T extends BlockEntity> Optional<T> getBlockEntity(BlockPos blockPos, BlockEntityType<T> blockEntityType) {
|
|
||||||
return parent.getBlockEntity(blockPos, blockEntityType);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BlockState getBlockState(BlockPos blockPos) {
|
public BlockState getBlockState(BlockPos blockPos) {
|
||||||
return parent.getBlockState(blockPos);
|
return parent.getBlockState(blockPos);
|
||||||
@@ -136,11 +151,6 @@ public class TintGetterOverrideSmooth implements BlockAndTintGetter {
|
|||||||
return parent.getBlockStates(aABB);
|
return parent.getBlockStates(aABB);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public BlockHitResult isBlockInLine(ClipBlockStateContext clipBlockStateContext) {
|
|
||||||
return parent.isBlockInLine(clipBlockStateContext);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BlockHitResult clip(ClipContext clipContext) {
|
public BlockHitResult clip(ClipContext clipContext) {
|
||||||
return parent.clip(clipContext);
|
return parent.clip(clipContext);
|
||||||
@@ -162,6 +172,22 @@ public class TintGetterOverrideSmooth implements BlockAndTintGetter {
|
|||||||
return parent.getBlockFloorHeight(blockPos);
|
return parent.getBlockFloorHeight(blockPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMaxBuildHeight() {
|
||||||
|
return parent.getMaxBuildHeight();
|
||||||
|
}
|
||||||
|
|
||||||
|
#if POST_MC_1_17_1
|
||||||
|
@Override
|
||||||
|
public <T extends BlockEntity> Optional<T> getBlockEntity(BlockPos blockPos, BlockEntityType<T> blockEntityType) {
|
||||||
|
return parent.getBlockEntity(blockPos, blockEntityType);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BlockHitResult isBlockInLine(ClipBlockStateContext clipBlockStateContext) {
|
||||||
|
return parent.isBlockInLine(clipBlockStateContext);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getHeight() {
|
public int getHeight() {
|
||||||
return parent.getHeight();
|
return parent.getHeight();
|
||||||
@@ -172,11 +198,6 @@ public class TintGetterOverrideSmooth implements BlockAndTintGetter {
|
|||||||
return parent.getMinBuildHeight();
|
return parent.getMinBuildHeight();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getMaxBuildHeight() {
|
|
||||||
return parent.getMaxBuildHeight();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getSectionsCount() {
|
public int getSectionsCount() {
|
||||||
return parent.getSectionsCount();
|
return parent.getSectionsCount();
|
||||||
@@ -216,4 +237,5 @@ public class TintGetterOverrideSmooth implements BlockAndTintGetter {
|
|||||||
public int getSectionYFromSectionIndex(int i) {
|
public int getSectionYFromSectionIndex(int i) {
|
||||||
return parent.getSectionYFromSectionIndex(i);
|
return parent.getSectionYFromSectionIndex(i);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|||||||
+91
@@ -0,0 +1,91 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
|
||||||
|
* licensed under the GNU LGPL v3 License.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2020-2022 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.lod.common.wrappers.block;
|
||||||
|
|
||||||
|
import com.seibel.lod.common.LodCommonMain;
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.core.Direction;
|
||||||
|
import net.minecraft.core.Holder;
|
||||||
|
import net.minecraft.world.level.*;
|
||||||
|
import net.minecraft.world.level.biome.Biome;
|
||||||
|
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||||
|
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||||
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
|
import net.minecraft.world.level.lighting.LevelLightEngine;
|
||||||
|
import net.minecraft.world.level.material.FluidState;
|
||||||
|
import net.minecraft.world.phys.AABB;
|
||||||
|
import net.minecraft.world.phys.BlockHitResult;
|
||||||
|
import net.minecraft.world.phys.Vec3;
|
||||||
|
import net.minecraft.world.phys.shapes.VoxelShape;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
public class TintWithoutLevelOverrider implements BlockAndTintGetter {
|
||||||
|
final BiomeWrapper biome;
|
||||||
|
|
||||||
|
public TintWithoutLevelOverrider(BiomeWrapper biome) {
|
||||||
|
this.biome = biome;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public int getBlockTint(BlockPos blockPos, ColorResolver colorResolver) {
|
||||||
|
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) {
|
||||||
|
#if POST_MC_1_18_2
|
||||||
|
return biome.value();
|
||||||
|
#else
|
||||||
|
return biome;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float getShade(Direction direction, boolean shade) {
|
||||||
|
throw new UnsupportedOperationException("ERROR: getShade() called on TintWithoutLevelOverrider. Object is for tinting only.");
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public LevelLightEngine getLightEngine() {
|
||||||
|
throw new UnsupportedOperationException("ERROR: getLightEngine() called on TintWithoutLevelOverrider. Object is for tinting only.");
|
||||||
|
}
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public BlockEntity getBlockEntity(BlockPos pos) {
|
||||||
|
throw new UnsupportedOperationException("ERROR: getBlockEntity() called on TintWithoutLevelOverrider. Object is for tinting only.");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BlockState getBlockState(BlockPos pos) {
|
||||||
|
throw new UnsupportedOperationException("ERROR: getBlockState() called on TintWithoutLevelOverrider. Object is for tinting only.");
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public FluidState getFluidState(BlockPos pos) {
|
||||||
|
throw new UnsupportedOperationException("ERROR: getFluidState() called on TintWithoutLevelOverrider. Object is for tinting only.");
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public int getHeight() {
|
||||||
|
throw new UnsupportedOperationException("ERROR: getHeight() called on TintWithoutLevelOverrider. Object is for tinting only.");
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public int getMinBuildHeight() {
|
||||||
|
throw new UnsupportedOperationException("ERROR: getMinBuildHeight() called on TintWithoutLevelOverrider. Object is for tinting only.");
|
||||||
|
}
|
||||||
|
}
|
||||||
+115
@@ -0,0 +1,115 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
|
||||||
|
* licensed under the GNU LGPL v3 License.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2020-2022 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.lod.common.wrappers.block;
|
||||||
|
|
||||||
|
import com.seibel.lod.common.LodCommonMain;
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.core.Cursor3D;
|
||||||
|
import net.minecraft.core.Direction;
|
||||||
|
import net.minecraft.core.Holder;
|
||||||
|
import net.minecraft.world.level.BlockAndTintGetter;
|
||||||
|
import net.minecraft.world.level.ColorResolver;
|
||||||
|
import net.minecraft.world.level.biome.Biome;
|
||||||
|
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||||
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
|
import net.minecraft.world.level.lighting.LevelLightEngine;
|
||||||
|
import net.minecraft.world.level.material.FluidState;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
public class TintWithoutLevelSmoothOverrider implements BlockAndTintGetter {
|
||||||
|
final BiomeWrapper biome;
|
||||||
|
public int smoothingRange;
|
||||||
|
|
||||||
|
public TintWithoutLevelSmoothOverrider(BiomeWrapper biome, int smoothingRange) {
|
||||||
|
this.biome = biome;
|
||||||
|
this.smoothingRange = smoothingRange;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public int getBlockTint(BlockPos blockPos, ColorResolver colorResolver) {
|
||||||
|
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) {
|
||||||
|
#if POST_MC_1_18_2
|
||||||
|
return biome.value();
|
||||||
|
#else
|
||||||
|
return biome;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// public int calculateBlockTint(BlockPos blockPos, ColorResolver colorResolver)
|
||||||
|
// {
|
||||||
|
// int i = smoothingRange;
|
||||||
|
// if (i == 0)
|
||||||
|
// return colorResolver.getColor(_getBiome(blockPos), blockPos.getX(), blockPos.getZ());
|
||||||
|
// int j = (i * 2 + 1) * (i * 2 + 1);
|
||||||
|
// int k = 0;
|
||||||
|
// int l = 0;
|
||||||
|
// int m = 0;
|
||||||
|
// Cursor3D cursor3D = new Cursor3D(blockPos.getX() - i, blockPos.getY(), blockPos.getZ() - i, blockPos.getX() + i, blockPos.getY(), blockPos.getZ() + i);
|
||||||
|
// BlockPos.MutableBlockPos mutableBlockPos = new BlockPos.MutableBlockPos();
|
||||||
|
// while (cursor3D.advance())
|
||||||
|
// {
|
||||||
|
// mutableBlockPos.set(cursor3D.nextX(), cursor3D.nextY(), cursor3D.nextZ());
|
||||||
|
// int n;
|
||||||
|
// if (LodCommonMain.forgeMethodCaller != null) {
|
||||||
|
// n = LodCommonMain.forgeMethodCaller.colorResolverGetColor(colorResolver, _getBiome(mutableBlockPos),
|
||||||
|
// mutableBlockPos.getX(), mutableBlockPos.getZ());
|
||||||
|
// } else {
|
||||||
|
// n = colorResolver.getColor(_getBiome(mutableBlockPos), mutableBlockPos.getX(), mutableBlockPos.getZ());
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// k += (n & 0xFF0000) >> 16;
|
||||||
|
// l += (n & 0xFF00) >> 8;
|
||||||
|
// m += n & 0xFF;
|
||||||
|
// }
|
||||||
|
// return (k / j & 0xFF) << 16 | (l / j & 0xFF) << 8 | m / j & 0xFF;
|
||||||
|
// }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float getShade(Direction direction, boolean shade) {
|
||||||
|
throw new UnsupportedOperationException("ERROR: getShade() called on TintWithoutLevelOverrider. Object is for tinting only.");
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public LevelLightEngine getLightEngine() {
|
||||||
|
throw new UnsupportedOperationException("ERROR: getLightEngine() called on TintWithoutLevelOverrider. Object is for tinting only.");
|
||||||
|
}
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public BlockEntity getBlockEntity(BlockPos pos) {
|
||||||
|
throw new UnsupportedOperationException("ERROR: getBlockEntity() called on TintWithoutLevelOverrider. Object is for tinting only.");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BlockState getBlockState(BlockPos pos) {
|
||||||
|
throw new UnsupportedOperationException("ERROR: getBlockState() called on TintWithoutLevelOverrider. Object is for tinting only.");
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public FluidState getFluidState(BlockPos pos) {
|
||||||
|
throw new UnsupportedOperationException("ERROR: getFluidState() called on TintWithoutLevelOverrider. Object is for tinting only.");
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public int getHeight() {
|
||||||
|
throw new UnsupportedOperationException("ERROR: getHeight() called on TintWithoutLevelOverrider. Object is for tinting only.");
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public int getMinBuildHeight() {
|
||||||
|
throw new UnsupportedOperationException("ERROR: getMinBuildHeight() called on TintWithoutLevelOverrider. Object is for tinting only.");
|
||||||
|
}
|
||||||
|
}
|
||||||
+25
@@ -0,0 +1,25 @@
|
|||||||
|
package com.seibel.lod.common.wrappers.block.cache;
|
||||||
|
|
||||||
|
import com.seibel.lod.common.wrappers.block.BiomeWrapper;
|
||||||
|
import com.seibel.lod.common.wrappers.world.ClientLevelWrapper;
|
||||||
|
import com.seibel.lod.core.pos.DhBlockPos;
|
||||||
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
|
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
public class ClientBlockDetailMap {
|
||||||
|
private final ConcurrentHashMap<BlockState, ClientBlockStateCache> blockCache = new ConcurrentHashMap<>();
|
||||||
|
//private final ConcurrentHashMap<#if PRE_MC_1_18_2 Biome #else Holder<Biome> #endif, Biome> biomeMap = new ConcurrentHashMap<>();
|
||||||
|
private final ClientLevelWrapper level;
|
||||||
|
public ClientBlockDetailMap(ClientLevelWrapper level) { this.level = level; }
|
||||||
|
|
||||||
|
public ClientBlockStateCache getBlockStateData(BlockState state, DhBlockPos pos) { //TODO: Allow a per pos unique setting
|
||||||
|
return blockCache.computeIfAbsent(state, (s) -> new ClientBlockStateCache(s, level, new DhBlockPos(0,0,0)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clear() { blockCache.clear(); }
|
||||||
|
|
||||||
|
public int getColor(BlockState state, BiomeWrapper biome, DhBlockPos pos) {
|
||||||
|
return getBlockStateData(state, pos).getAndResolveFaceColor(biome);
|
||||||
|
}
|
||||||
|
}
|
||||||
+186
@@ -0,0 +1,186 @@
|
|||||||
|
package com.seibel.lod.common.wrappers.block.cache;
|
||||||
|
|
||||||
|
import com.seibel.lod.common.wrappers.McObjectConverter;
|
||||||
|
import com.seibel.lod.common.wrappers.block.*;
|
||||||
|
import com.seibel.lod.core.logging.DhLoggerBuilder;
|
||||||
|
import com.seibel.lod.core.pos.DhBlockPos;
|
||||||
|
import com.seibel.lod.core.util.ColorUtil;
|
||||||
|
import com.seibel.lod.core.wrapperInterfaces.world.IClientLevelWrapper;
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.client.renderer.block.model.BakedQuad;
|
||||||
|
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.core.Direction;
|
||||||
|
import net.minecraft.world.level.LevelReader;
|
||||||
|
import net.minecraft.world.level.block.Block;
|
||||||
|
import net.minecraft.world.level.block.FlowerBlock;
|
||||||
|
import net.minecraft.world.level.block.LeavesBlock;
|
||||||
|
import net.minecraft.world.level.block.RotatedPillarBlock;
|
||||||
|
#if POST_MC_1_19
|
||||||
|
import net.minecraft.util.RandomSource;
|
||||||
|
#endif
|
||||||
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @version 2022-9-16
|
||||||
|
*/
|
||||||
|
public class ClientBlockStateCache
|
||||||
|
{
|
||||||
|
|
||||||
|
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
|
||||||
|
|
||||||
|
#if PRE_MC_1_19
|
||||||
|
public static final Random random = new Random(0);
|
||||||
|
#else
|
||||||
|
public static final RandomSource random = RandomSource.create();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
public final BlockState state;
|
||||||
|
public final LevelReader level;
|
||||||
|
public final BlockPos pos;
|
||||||
|
public ClientBlockStateCache(BlockState blockState, IClientLevelWrapper samplingLevel, DhBlockPos samplingPos) {
|
||||||
|
state = blockState;
|
||||||
|
level = (LevelReader) samplingLevel.getWrappedMcObject_UNSAFE();
|
||||||
|
pos = McObjectConverter.Convert(samplingPos);
|
||||||
|
resolveColors();
|
||||||
|
//LOGGER.info("ClientBlocKCache created for {}", blockState);
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean isColorResolved = false;
|
||||||
|
int baseColor = 0; //TODO: Impl per-face color
|
||||||
|
boolean needShade = true;
|
||||||
|
boolean needPostTinting = false;
|
||||||
|
int tintIndex = 0;
|
||||||
|
|
||||||
|
|
||||||
|
public static final int FLOWER_COLOR_SCALE = 5;
|
||||||
|
|
||||||
|
enum ColorMode {
|
||||||
|
Default,
|
||||||
|
Flower,
|
||||||
|
Leaves;
|
||||||
|
static ColorMode getColorMode(Block b) {
|
||||||
|
if (b instanceof LeavesBlock) return Leaves;
|
||||||
|
if (b instanceof FlowerBlock) return Flower;
|
||||||
|
return Default;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//TODO: Perhaps make this not just use the first frame?
|
||||||
|
private static int calculateColorFromTexture(TextureAtlasSprite texture, ColorMode colorMode) {
|
||||||
|
int count = 0;
|
||||||
|
double alpha = 0;
|
||||||
|
double red = 0;
|
||||||
|
double green = 0;
|
||||||
|
double blue = 0;
|
||||||
|
int tempColor;
|
||||||
|
{
|
||||||
|
// textures normally use u and v instead of x and y
|
||||||
|
for (int u = 0; u < texture.getWidth(); u++)
|
||||||
|
{
|
||||||
|
for (int v = 0; v < texture.getHeight(); v++)
|
||||||
|
{
|
||||||
|
//note: Minecraft color format is: 0xAA BB GG RR
|
||||||
|
//________ DH mod color format is: 0xAA RR GG BB
|
||||||
|
//OpenGL RGBA format native order: 0xRR GG BB AA
|
||||||
|
//_ OpenGL RGBA format Java Order: 0xAA BB GG RR
|
||||||
|
tempColor = TextureAtlasSpriteWrapper.getPixelRGBA(texture, 0, u, v);
|
||||||
|
|
||||||
|
double r = ((tempColor & 0x000000FF) )/255.;
|
||||||
|
double g = ((tempColor & 0x0000FF00) >>> 8)/255.;
|
||||||
|
double b = ((tempColor & 0x00FF0000) >>> 16)/255.;
|
||||||
|
double a = ((tempColor & 0xFF000000) >>> 24)/255.;
|
||||||
|
int scale = 1;
|
||||||
|
|
||||||
|
if (colorMode == ColorMode.Leaves) {
|
||||||
|
r *= a;
|
||||||
|
g *= a;
|
||||||
|
b *= a;
|
||||||
|
a = 1.;
|
||||||
|
} else if (a==0.) {
|
||||||
|
continue;
|
||||||
|
} else if (colorMode == ColorMode.Flower && (g+0.1<b || g+0.1<r)) {
|
||||||
|
scale = FLOWER_COLOR_SCALE;
|
||||||
|
}
|
||||||
|
|
||||||
|
count += scale;
|
||||||
|
alpha += a*a*scale;
|
||||||
|
red += r*r*scale;
|
||||||
|
green += g*g*scale;
|
||||||
|
blue += b*b*scale;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count == 0)
|
||||||
|
// this block is entirely transparent
|
||||||
|
tempColor = ColorUtil.rgbToInt(0,255,255,255);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// determine the average color
|
||||||
|
tempColor = ColorUtil.rgbToInt(
|
||||||
|
(int) (Math.sqrt(alpha/count)*255.),
|
||||||
|
(int) (Math.sqrt(red / count)*255.),
|
||||||
|
(int) (Math.sqrt(green / count)*255.),
|
||||||
|
(int) (Math.sqrt(blue / count)*255.));
|
||||||
|
}
|
||||||
|
return tempColor;
|
||||||
|
}
|
||||||
|
private static final Direction[] DIRECTION_ORDER = {Direction.UP, Direction.NORTH, Direction.EAST, Direction.WEST, Direction.SOUTH, Direction.DOWN};
|
||||||
|
|
||||||
|
private void resolveColors() {
|
||||||
|
if (isColorResolved) return;
|
||||||
|
if (state.getFluidState().isEmpty()) {
|
||||||
|
List<BakedQuad> quads = null;
|
||||||
|
for (Direction direction : DIRECTION_ORDER)
|
||||||
|
{
|
||||||
|
quads = Minecraft.getInstance().getModelManager().getBlockModelShaper().
|
||||||
|
getBlockModel(state).getQuads(state, direction, random);
|
||||||
|
if (quads != null && !quads.isEmpty() &&
|
||||||
|
!(state.getBlock() instanceof RotatedPillarBlock && direction == Direction.UP))
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
if (quads == null || quads.isEmpty()) {
|
||||||
|
quads = Minecraft.getInstance().getModelManager().getBlockModelShaper().
|
||||||
|
getBlockModel(state).getQuads(state, null, random);
|
||||||
|
}
|
||||||
|
if (quads != null && !quads.isEmpty()) {
|
||||||
|
needPostTinting = quads.get(0).isTinted();
|
||||||
|
needShade = quads.get(0).isShade();
|
||||||
|
tintIndex = quads.get(0).getTintIndex();
|
||||||
|
baseColor = calculateColorFromTexture(
|
||||||
|
#if PRE_MC_1_17_1 quads.get(0).sprite,
|
||||||
|
#else quads.get(0).getSprite(), #endif
|
||||||
|
ColorMode.getColorMode(state.getBlock()));
|
||||||
|
} else { // Backup method.
|
||||||
|
needPostTinting = false;
|
||||||
|
needShade = false;
|
||||||
|
tintIndex = 0;
|
||||||
|
baseColor = calculateColorFromTexture(Minecraft.getInstance().getModelManager().getBlockModelShaper().getParticleIcon(state),
|
||||||
|
ColorMode.getColorMode(state.getBlock()));
|
||||||
|
}
|
||||||
|
} else { // Liquid Block
|
||||||
|
needPostTinting = true;
|
||||||
|
needShade = false;
|
||||||
|
tintIndex = 0;
|
||||||
|
baseColor = calculateColorFromTexture(Minecraft.getInstance().getModelManager().getBlockModelShaper().getParticleIcon(state),
|
||||||
|
ColorMode.getColorMode(state.getBlock()));
|
||||||
|
}
|
||||||
|
isColorResolved = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getAndResolveFaceColor(BiomeWrapper biome)
|
||||||
|
{
|
||||||
|
// FIXME: impl per-face colors
|
||||||
|
if (!needPostTinting) return baseColor;
|
||||||
|
int tintColor = Minecraft.getInstance().getBlockColors()
|
||||||
|
.getColor(state, new TintWithoutLevelOverrider(biome), pos, tintIndex);
|
||||||
|
if (tintColor == -1) return baseColor;
|
||||||
|
return ColorUtil.multiplyARGBwithRGB(baseColor, tintColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+41
@@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
|
||||||
|
* licensed under the GNU LGPL v3 License.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2020-2022 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.lod.common.wrappers.block.cache;
|
||||||
|
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
import com.seibel.lod.common.wrappers.world.ServerLevelWrapper;
|
||||||
|
import com.seibel.lod.core.pos.DhBlockPos;
|
||||||
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
|
|
||||||
|
|
||||||
|
public class ServerBlockDetailMap
|
||||||
|
{
|
||||||
|
private final ConcurrentHashMap<BlockState, ServerBlockStateCache> blockCache = new ConcurrentHashMap<>();
|
||||||
|
//private final ConcurrentHashMap<#if PRE_MC_1_18_2 Biome #else Holder<Biome> #endif, Biome> biomeMap = new ConcurrentHashMap<>();
|
||||||
|
private final ServerLevelWrapper level;
|
||||||
|
public ServerBlockDetailMap(ServerLevelWrapper level) { this.level = level; }
|
||||||
|
|
||||||
|
public ServerBlockStateCache getBlockStateData(BlockState state, DhBlockPos pos) { //TODO: Allow a per pos unique setting
|
||||||
|
return blockCache.computeIfAbsent(state, (s) -> new ServerBlockStateCache(s, level, new DhBlockPos(0,0,0)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clear() { blockCache.clear(); }
|
||||||
|
}
|
||||||
+77
@@ -0,0 +1,77 @@
|
|||||||
|
package com.seibel.lod.common.wrappers.block.cache;
|
||||||
|
|
||||||
|
import com.seibel.lod.common.wrappers.McObjectConverter;
|
||||||
|
import com.seibel.lod.core.logging.DhLoggerBuilder;
|
||||||
|
import com.seibel.lod.core.pos.DhBlockPos;
|
||||||
|
import com.seibel.lod.core.wrapperInterfaces.world.ILevelWrapper;
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.core.Direction;
|
||||||
|
import net.minecraft.world.level.LevelReader;
|
||||||
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
|
import net.minecraft.world.phys.AABB;
|
||||||
|
import net.minecraft.world.phys.shapes.VoxelShape;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @version 2022-9-16
|
||||||
|
*/
|
||||||
|
public class ServerBlockStateCache
|
||||||
|
{
|
||||||
|
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
|
||||||
|
|
||||||
|
public final BlockState state;
|
||||||
|
public final LevelReader level;
|
||||||
|
public final BlockPos pos;
|
||||||
|
|
||||||
|
public ServerBlockStateCache(BlockState blockState, ILevelWrapper samplingLevel, DhBlockPos samplingPos) {
|
||||||
|
state = blockState;
|
||||||
|
level = (LevelReader) samplingLevel.getWrappedMcObject_UNSAFE();
|
||||||
|
pos = McObjectConverter.Convert(samplingPos);
|
||||||
|
resolveShapes();
|
||||||
|
//LOGGER.info("ServerBlockState created for {}", blockState);
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean noCollision = false;
|
||||||
|
boolean[] occludeFaces = null;
|
||||||
|
boolean[] fullFaces = null;
|
||||||
|
boolean isShapeResolved = false;
|
||||||
|
public void resolveShapes() {
|
||||||
|
if (isShapeResolved) return;
|
||||||
|
if (state.getFluidState().isEmpty()) {
|
||||||
|
noCollision = state.getCollisionShape(level, pos).isEmpty();
|
||||||
|
occludeFaces = new boolean[6];
|
||||||
|
if (state.canOcclude()) {
|
||||||
|
for (Direction dir : Direction.values()) {
|
||||||
|
// Note: isEmpty() isn't quite correct... best would be a isFull() or something...
|
||||||
|
occludeFaces[McObjectConverter.Convert(dir).ordinal()]
|
||||||
|
= !state.getFaceOcclusionShape(level, pos, dir).isEmpty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
VoxelShape voxelShape = state.getShape(level, pos);
|
||||||
|
fullFaces = new boolean[6];
|
||||||
|
if (!voxelShape.isEmpty()) {
|
||||||
|
for (Direction dir : Direction.values()) {
|
||||||
|
VoxelShape faceShape = voxelShape.getFaceShape(dir);
|
||||||
|
AABB aabb = faceShape.bounds();
|
||||||
|
boolean xFull = aabb.minX <= 0.01 && aabb.maxX >= 0.99;
|
||||||
|
boolean yFull = aabb.minY <= 0.01 && aabb.maxY >= 0.99;
|
||||||
|
boolean zFull = aabb.minZ <= 0.01 && aabb.maxZ >= 0.99;
|
||||||
|
fullFaces[McObjectConverter.Convert(dir).ordinal()] =
|
||||||
|
(xFull || dir.getAxis().equals(Direction.Axis.X))
|
||||||
|
&& (yFull || dir.getAxis().equals(Direction.Axis.Y))
|
||||||
|
&& (zFull || dir.getAxis().equals(Direction.Axis.Z));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else { // Liquid Block. Treat as full block
|
||||||
|
occludeFaces = new boolean[6];
|
||||||
|
Arrays.fill(occludeFaces, true);
|
||||||
|
fullFaces = new boolean[6];
|
||||||
|
Arrays.fill(fullFaces, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,136 +0,0 @@
|
|||||||
package com.seibel.lod.common.wrappers.chunk;
|
|
||||||
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
import com.seibel.lod.core.util.LevelPosUtil;
|
|
||||||
import com.seibel.lod.core.util.LodUtil;
|
|
||||||
import com.seibel.lod.core.wrapperInterfaces.block.AbstractBlockPosWrapper;
|
|
||||||
import com.seibel.lod.core.wrapperInterfaces.chunk.AbstractChunkPosWrapper;
|
|
||||||
import com.seibel.lod.common.wrappers.block.BlockPosWrapper;
|
|
||||||
|
|
||||||
import net.minecraft.core.BlockPos;
|
|
||||||
import net.minecraft.world.level.ChunkPos;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author James Seibel
|
|
||||||
* @version 11-21-2021
|
|
||||||
*/
|
|
||||||
public class ChunkPosWrapper extends AbstractChunkPosWrapper
|
|
||||||
{
|
|
||||||
private final net.minecraft.world.level.ChunkPos chunkPos;
|
|
||||||
|
|
||||||
public ChunkPosWrapper()
|
|
||||||
{
|
|
||||||
this.chunkPos = new ChunkPos(0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ChunkPosWrapper(BlockPos blockPos)
|
|
||||||
{
|
|
||||||
this.chunkPos = new ChunkPos(blockPos);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ChunkPosWrapper(AbstractChunkPosWrapper newChunkPos)
|
|
||||||
{
|
|
||||||
this.chunkPos = ((ChunkPosWrapper) newChunkPos).chunkPos;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ChunkPosWrapper(AbstractBlockPosWrapper blockPos)
|
|
||||||
{
|
|
||||||
this.chunkPos = new ChunkPos(((BlockPosWrapper) blockPos).getBlockPos());
|
|
||||||
}
|
|
||||||
|
|
||||||
public ChunkPosWrapper(int chunkX, int chunkZ)
|
|
||||||
{
|
|
||||||
this.chunkPos = new ChunkPos(chunkX, chunkZ);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ChunkPosWrapper(long l) {
|
|
||||||
this.chunkPos = new ChunkPos(l);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public ChunkPosWrapper(ChunkPos pos)
|
|
||||||
{
|
|
||||||
this.chunkPos = pos;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getX()
|
|
||||||
{
|
|
||||||
return chunkPos.x;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getZ()
|
|
||||||
{
|
|
||||||
return chunkPos.z;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getMinBlockX()
|
|
||||||
{
|
|
||||||
return chunkPos.getMinBlockX();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getMinBlockZ()
|
|
||||||
{
|
|
||||||
return chunkPos.getMinBlockZ();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getRegionX()
|
|
||||||
{
|
|
||||||
return LevelPosUtil.convert(LodUtil.CHUNK_DETAIL_LEVEL, chunkPos.x, LodUtil.REGION_DETAIL_LEVEL);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getRegionZ()
|
|
||||||
{
|
|
||||||
return LevelPosUtil.convert(LodUtil.CHUNK_DETAIL_LEVEL, chunkPos.z, LodUtil.REGION_DETAIL_LEVEL);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long getLong() {
|
|
||||||
return chunkPos.toLong();
|
|
||||||
}
|
|
||||||
|
|
||||||
public ChunkPos getChunkPos()
|
|
||||||
{
|
|
||||||
return chunkPos;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object o)
|
|
||||||
{
|
|
||||||
// If the object is compared with itself then return true
|
|
||||||
if (o == this) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
// Check if o is an instance of RegionPos or not
|
|
||||||
if (!(o instanceof ChunkPosWrapper)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
ChunkPosWrapper c = (ChunkPosWrapper) o;
|
|
||||||
return c.chunkPos.equals(chunkPos);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode()
|
|
||||||
{
|
|
||||||
return Objects.hash(chunkPos);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AbstractBlockPosWrapper getWorldPosition()
|
|
||||||
{
|
|
||||||
// the parameter here is the y position
|
|
||||||
BlockPos blockPos = chunkPos.getMiddleBlockPosition(0);
|
|
||||||
return new BlockPosWrapper(blockPos.getX(), blockPos.getY(), blockPos.getZ());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,31 +1,51 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
|
||||||
|
* licensed under the GNU LGPL v3 License.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2020-2022 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.lod.common.wrappers.chunk;
|
package com.seibel.lod.common.wrappers.chunk;
|
||||||
|
|
||||||
import com.seibel.lod.common.wrappers.block.BlockDetailWrapper;
|
import com.seibel.lod.common.wrappers.block.BlockStateWrapper;
|
||||||
import com.seibel.lod.core.enums.LodDirection;
|
import com.seibel.lod.core.pos.DhBlockPos;
|
||||||
|
import com.seibel.lod.core.pos.DhChunkPos;
|
||||||
import com.seibel.lod.core.util.LevelPosUtil;
|
import com.seibel.lod.core.util.LevelPosUtil;
|
||||||
import com.seibel.lod.core.util.LodUtil;
|
import com.seibel.lod.core.util.LodUtil;
|
||||||
import com.seibel.lod.core.wrapperInterfaces.block.IBlockDetailWrapper;
|
import com.seibel.lod.core.wrapperInterfaces.block.IBlockStateWrapper;
|
||||||
import com.seibel.lod.core.wrapperInterfaces.chunk.IChunkWrapper;
|
import com.seibel.lod.core.wrapperInterfaces.chunk.IChunkWrapper;
|
||||||
import com.seibel.lod.core.wrapperInterfaces.world.IBiomeWrapper;
|
import com.seibel.lod.core.wrapperInterfaces.world.IBiomeWrapper;
|
||||||
|
|
||||||
import com.seibel.lod.common.wrappers.WrapperUtil;
|
import com.seibel.lod.common.wrappers.WrapperUtil;
|
||||||
import com.seibel.lod.common.wrappers.block.BlockDetailMap;
|
import com.seibel.lod.common.wrappers.block.BiomeWrapper;
|
||||||
import com.seibel.lod.common.wrappers.world.BiomeWrapper;
|
|
||||||
import com.seibel.lod.common.wrappers.worldGeneration.mimicObject.LightedWorldGenRegion;
|
import com.seibel.lod.common.wrappers.worldGeneration.mimicObject.LightedWorldGenRegion;
|
||||||
|
|
||||||
|
import com.seibel.lod.core.wrapperInterfaces.world.ILevelWrapper;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
|
#if POST_MC_1_17_1
|
||||||
import net.minecraft.core.QuartPos;
|
import net.minecraft.core.QuartPos;
|
||||||
|
#endif
|
||||||
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.block.LiquidBlockContainer;
|
|
||||||
import net.minecraft.world.level.block.SimpleWaterloggedBlock;
|
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
|
||||||
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
|
|
||||||
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.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;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author James Seibel
|
* @author James Seibel
|
||||||
@@ -34,24 +54,36 @@ import net.minecraft.world.level.levelgen.Heightmap;
|
|||||||
public class ChunkWrapper implements IChunkWrapper
|
public class ChunkWrapper implements IChunkWrapper
|
||||||
{
|
{
|
||||||
private final ChunkAccess chunk;
|
private final ChunkAccess chunk;
|
||||||
|
private final DhChunkPos chunkPos;
|
||||||
private final LevelReader lightSource;
|
private final LevelReader lightSource;
|
||||||
|
private final ILevelWrapper wrappedLevel;
|
||||||
|
|
||||||
|
|
||||||
public ChunkWrapper(ChunkAccess chunk, LevelReader lightSource)
|
public ChunkWrapper(ChunkAccess chunk, LevelReader lightSource, @Nullable ILevelWrapper wrappedLevel)
|
||||||
{
|
{
|
||||||
this.chunk = chunk;
|
this.chunk = chunk;
|
||||||
this.lightSource = lightSource;
|
this.lightSource = lightSource;
|
||||||
|
this.wrappedLevel = wrappedLevel;
|
||||||
|
chunkPos = new DhChunkPos(chunk.getPos().x, chunk.getPos().z);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getHeight(){
|
public int getHeight(){
|
||||||
|
#if PRE_MC_1_17_1
|
||||||
|
return 255;
|
||||||
|
#else
|
||||||
return chunk.getHeight();
|
return chunk.getHeight();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getMinBuildHeight()
|
public int getMinBuildHeight()
|
||||||
{
|
{
|
||||||
|
#if PRE_MC_1_17_1
|
||||||
|
return 0;
|
||||||
|
#else
|
||||||
return chunk.getMinBuildHeight();
|
return chunk.getMinBuildHeight();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public int getMaxBuildHeight()
|
public int getMaxBuildHeight()
|
||||||
@@ -68,39 +100,28 @@ public class ChunkWrapper implements IChunkWrapper
|
|||||||
@Override
|
@Override
|
||||||
public IBiomeWrapper getBiome(int x, int y, int z)
|
public IBiomeWrapper getBiome(int x, int y, int z)
|
||||||
{
|
{
|
||||||
#if MC_VERSION_1_18_2
|
//if (wrappedLevel != null) return wrappedLevel.getBiome(new DhBlockPos(x + getMinX(), y, z + getMinZ()));
|
||||||
|
|
||||||
|
#if PRE_MC_1_17_1
|
||||||
|
return BiomeWrapper.getBiomeWrapper(chunk.getBiomes().getNoiseBiome(
|
||||||
|
x >> 2, y >> 2, z >> 2));
|
||||||
|
#elif PRE_MC_1_18_1
|
||||||
|
return BiomeWrapper.getBiomeWrapper(chunk.getBiomes().getNoiseBiome(
|
||||||
|
QuartPos.fromBlock(x), QuartPos.fromBlock(y), QuartPos.fromBlock(z)));
|
||||||
|
#elif PRE_MC_1_18_2
|
||||||
return BiomeWrapper.getBiomeWrapper(chunk.getNoiseBiome(
|
return BiomeWrapper.getBiomeWrapper(chunk.getNoiseBiome(
|
||||||
QuartPos.fromBlock(x), QuartPos.fromBlock(y), QuartPos.fromBlock(z)).value());
|
QuartPos.fromBlock(x), QuartPos.fromBlock(y), QuartPos.fromBlock(z)));
|
||||||
#elif MC_VERSION_1_18_1
|
#else //Now returns a Holder<Biome> instead of Biome
|
||||||
return BiomeWrapper.getBiomeWrapper(chunk.getNoiseBiome(
|
return BiomeWrapper.getBiomeWrapper(chunk.getNoiseBiome(
|
||||||
QuartPos.fromBlock(x), QuartPos.fromBlock(y), QuartPos.fromBlock(z)));
|
QuartPos.fromBlock(x), QuartPos.fromBlock(y), QuartPos.fromBlock(z)));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IBlockDetailWrapper getBlockDetail(int x, int y, int z) {
|
public DhChunkPos getChunkPos() {
|
||||||
BlockPos pos = new BlockPos(x,y,z);
|
return chunkPos;
|
||||||
BlockState blockState = chunk.getBlockState(pos);
|
|
||||||
IBlockDetailWrapper blockDetail = BlockDetailMap.getOrMakeBlockDetailCache(blockState, pos, lightSource);
|
|
||||||
return blockDetail == BlockDetailWrapper.NULL_BLOCK_DETAIL ? null : blockDetail;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public IBlockDetailWrapper getBlockDetailAtFace(int x, int y, int z, LodDirection dir) {
|
|
||||||
int fy = y+dir.getNormal().y;
|
|
||||||
if (fy < getMinBuildHeight() || fy > getMaxBuildHeight()) return null;
|
|
||||||
BlockPos pos = new BlockPos(x+dir.getNormal().x,fy,z+dir.getNormal().z);
|
|
||||||
BlockState blockState;
|
|
||||||
if (blockPosInsideChunk(x,y,z))
|
|
||||||
blockState = chunk.getBlockState(pos);
|
|
||||||
else {
|
|
||||||
blockState = lightSource.getBlockState(pos);
|
|
||||||
}
|
|
||||||
if (blockState == null || blockState.isAir()) return null;
|
|
||||||
IBlockDetailWrapper blockDetail = BlockDetailMap.getOrMakeBlockDetailCache(blockState, pos, lightSource);
|
|
||||||
return blockDetail == BlockDetailWrapper.NULL_BLOCK_DETAIL ? null : blockDetail;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ChunkAccess getChunk() {
|
public ChunkAccess getChunk() {
|
||||||
return chunk;
|
return chunk;
|
||||||
}
|
}
|
||||||
@@ -127,7 +148,7 @@ public class ChunkWrapper implements IChunkWrapper
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getMaxY(int x, int z) {
|
public int getMaxY(int x, int z) {
|
||||||
return chunk.getHeight(Heightmap.Types.MOTION_BLOCKING, Math.floorMod(x, 16), Math.floorMod(z, 16));
|
return chunk.getHeight(Heightmap.Types.WORLD_SURFACE, Math.floorMod(x, 16), Math.floorMod(z, 16));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -154,38 +175,26 @@ public class ChunkWrapper implements IChunkWrapper
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isLightCorrect(){
|
public boolean isLightCorrect(){
|
||||||
//return true;
|
#if PRE_MC_1_18_1
|
||||||
if (chunk instanceof LevelChunk) {
|
return true;
|
||||||
return ((LevelChunk) chunk).isClientLightReady();
|
#else
|
||||||
}
|
//if (chunk instanceof LevelChunk) {
|
||||||
|
// return ((LevelChunk) chunk).isClientLightReady();
|
||||||
|
//}
|
||||||
return chunk.isLightCorrect();
|
return chunk.isLightCorrect();
|
||||||
}
|
#endif
|
||||||
|
|
||||||
public boolean isWaterLogged(int x, int y, int z)
|
|
||||||
{
|
|
||||||
BlockState blockState = chunk.getBlockState(new BlockPos(x,y,z));
|
|
||||||
|
|
||||||
//This type of block is always in water
|
|
||||||
return (!(blockState.getBlock() instanceof LiquidBlockContainer) && (blockState.getBlock() instanceof SimpleWaterloggedBlock))
|
|
||||||
&& (blockState.hasProperty(BlockStateProperties.WATERLOGGED) && blockState.getValue(BlockStateProperties.WATERLOGGED));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getEmittedBrightness(int x, int y, int z)
|
|
||||||
{
|
|
||||||
return chunk.getLightEmission(new BlockPos(x,y,z));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getBlockLight(int x, int y, int z) {
|
public int getBlockLight(int x, int y, int z) {
|
||||||
if (lightSource == null) return -1;
|
if (lightSource == null) return -1;
|
||||||
return lightSource.getBrightness(LightLayer.BLOCK, new BlockPos(x,y,z));
|
return lightSource.getBrightness(LightLayer.BLOCK, new BlockPos(x + getMinX(),y,z + getMinZ()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getSkyLight(int x, int y, int z) {
|
public int getSkyLight(int x, int y, int z) {
|
||||||
if (lightSource == null) return -1;
|
if (lightSource == null) return -1;
|
||||||
return lightSource.getBrightness(LightLayer.SKY, new BlockPos(x,y,z));
|
return lightSource.getBrightness(LightLayer.SKY, new BlockPos(x + getMinX(),y,z + getMinZ()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -194,7 +203,7 @@ public class ChunkWrapper implements IChunkWrapper
|
|||||||
for (int dx = -1; dx <= 1; dx++) {
|
for (int dx = -1; dx <= 1; dx++) {
|
||||||
for (int dz = -1; dz <= 1; dz++) {
|
for (int dz = -1; dz <= 1; dz++) {
|
||||||
if (dx==0 && dz==0) continue;
|
if (dx==0 && dz==0) continue;
|
||||||
if (lightSource.getChunk(dx+getChunkPosX(), dz+getChunkPosZ(), ChunkStatus.BIOMES, false) == null) return false;
|
if (lightSource.getChunk(dx+chunk.getPos().x, dz+chunk.getPos().z, ChunkStatus.BIOMES, false) == null) return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -204,5 +213,20 @@ public class ChunkWrapper implements IChunkWrapper
|
|||||||
{
|
{
|
||||||
return lightSource;
|
return lightSource;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return chunk.getClass().getSimpleName() + chunk.getPos();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IBlockStateWrapper getBlockState(int x, int y, int z) {
|
||||||
|
//if (wrappedLevel != null) return wrappedLevel.getBlockState(new DhBlockPos(x + getMinX(), y, z + getMinZ()));
|
||||||
|
return BlockStateWrapper.fromBlockState(chunk.getBlockState(new BlockPos(x,y,z)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isStillValid() {
|
||||||
|
return wrappedLevel == null || wrappedLevel.tryGetChunk(chunkPos) == this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,762 +0,0 @@
|
|||||||
package com.seibel.lod.common.wrappers.config;
|
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
|
||||||
import java.nio.file.Files;
|
|
||||||
import java.nio.file.Path;
|
|
||||||
import java.util.AbstractMap;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.function.BiFunction;
|
|
||||||
import java.util.function.Function;
|
|
||||||
import java.util.function.Predicate;
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
// Logger (for debug stuff)
|
|
||||||
|
|
||||||
import org.apache.logging.log4j.LogManager;
|
|
||||||
import org.apache.logging.log4j.Logger;
|
|
||||||
|
|
||||||
// Uses https://github.com/TheElectronWill/night-config for toml (only for Fabric since Forge already includes this)
|
|
||||||
|
|
||||||
import com.electronwill.nightconfig.core.file.CommentedFileConfig;
|
|
||||||
|
|
||||||
// Gets info from our own mod
|
|
||||||
|
|
||||||
import com.seibel.lod.common.LodCommonMain;
|
|
||||||
import com.seibel.lod.core.ModInfo;
|
|
||||||
import com.seibel.lod.core.config.*;
|
|
||||||
|
|
||||||
// Minecraft imports
|
|
||||||
|
|
||||||
import com.mojang.blaze3d.vertex.PoseStack;
|
|
||||||
import net.minecraft.ChatFormatting;
|
|
||||||
import net.minecraft.client.Minecraft;
|
|
||||||
import net.minecraft.client.gui.Font;
|
|
||||||
import net.minecraft.client.gui.GuiComponent;
|
|
||||||
import net.minecraft.client.gui.components.AbstractWidget;
|
|
||||||
import net.minecraft.client.gui.components.Button;
|
|
||||||
import net.minecraft.client.gui.components.ContainerObjectSelectionList;
|
|
||||||
import net.minecraft.client.gui.components.EditBox;
|
|
||||||
import net.minecraft.client.gui.components.events.GuiEventListener;
|
|
||||||
import net.minecraft.client.gui.screens.Screen;
|
|
||||||
import net.minecraft.network.chat.CommonComponents;
|
|
||||||
import net.minecraft.network.chat.Component;
|
|
||||||
import net.minecraft.network.chat.TextComponent;
|
|
||||||
import net.minecraft.network.chat.TranslatableComponent;
|
|
||||||
import net.minecraft.client.resources.language.I18n; // translation
|
|
||||||
import net.minecraft.client.gui.narration.NarratableEntry; // Remove in 1.16
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Based upon TinyConfig
|
|
||||||
* https://github.com/Minenash/TinyConfig
|
|
||||||
*
|
|
||||||
* This config should work for both Fabric and Forge as long as you use Mojang mappings
|
|
||||||
*
|
|
||||||
* Credits to Motschen
|
|
||||||
*
|
|
||||||
* @author coolGi2007
|
|
||||||
* @version 1-14-2022
|
|
||||||
*/
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public abstract class ConfigGui
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
TODO list
|
|
||||||
|
|
||||||
Fix floats not working
|
|
||||||
Make a wiki
|
|
||||||
Make it so you can enable and disable buttons from showing
|
|
||||||
Make min and max not final
|
|
||||||
Move the ConfigScreenConfigs class to the config class that extends this
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
List of hacky things that are done that should be done properly
|
|
||||||
|
|
||||||
The buttons that don't show are still loaded but just not rendered
|
|
||||||
The screen with is set to double so the scroll bar doesn't show
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
private static final Pattern INTEGER_ONLY_REGEX = Pattern.compile("(-?[0-9]*)");
|
|
||||||
private static final Pattern DECIMAL_ONLY_REGEX = Pattern.compile("-?([\\d]+\\.?[\\d]*|[\\d]*\\.?[\\d]+|\\.)");
|
|
||||||
|
|
||||||
private static final List<EntryInfo> entries = new ArrayList<>();
|
|
||||||
public static final Map<String,EntryInfo> entryMap = new HashMap<>();
|
|
||||||
|
|
||||||
// Change these to your own mod
|
|
||||||
private static final String MOD_NAME = ModInfo.NAME; // For file saving and identifying
|
|
||||||
private static final String MOD_NAME_READABLE = ModInfo.READABLE_NAME; // For logs
|
|
||||||
// private static final Logger LOGGER = ApiShared.LOGGER; // For logs
|
|
||||||
private static final Logger LOGGER = LogManager.getLogger(ModInfo.NAME); // For logs (this inits before ClientAPI so this is a temp fix)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//==============//
|
|
||||||
// Initializers //
|
|
||||||
//==============//
|
|
||||||
|
|
||||||
private static class ConfigScreenConfigs
|
|
||||||
{
|
|
||||||
// This contains all the configs for the configs
|
|
||||||
public static final int SpaceFromRightScreen = 10;
|
|
||||||
public static final int ButtonWidthSpacing = 5;
|
|
||||||
public static final int ResetButtonWidth = 40;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class EntryInfo<T>
|
|
||||||
{
|
|
||||||
Field field;
|
|
||||||
Object widget;
|
|
||||||
int width = 0;
|
|
||||||
int max;
|
|
||||||
Map.Entry<EditBox, Component> error;
|
|
||||||
Object defaultValue;
|
|
||||||
Object value;
|
|
||||||
String tempValue;
|
|
||||||
boolean inLimits = true;
|
|
||||||
TranslatableComponent name;
|
|
||||||
int index;
|
|
||||||
/** Hides the button */
|
|
||||||
boolean hideOption = false;
|
|
||||||
/** This asks if it is a button to goto a new screen */
|
|
||||||
boolean screenButton = false;
|
|
||||||
/** This is only called if button is true */
|
|
||||||
String gotoScreen = "";
|
|
||||||
String category;
|
|
||||||
Class<T> varClass;
|
|
||||||
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
boolean fileComment = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Path configFilePath;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static void init(Class<?> config)
|
|
||||||
{
|
|
||||||
Minecraft mc = Minecraft.getInstance();
|
|
||||||
configFilePath = mc.gameDirectory.toPath().resolve("config").resolve(MOD_NAME + ".toml");
|
|
||||||
|
|
||||||
initNestedClass(config, "");
|
|
||||||
|
|
||||||
for (EntryInfo info : entries) {
|
|
||||||
if (info.field.isAnnotationPresent(ConfigAnnotations.Entry.class)) {
|
|
||||||
try {
|
|
||||||
info.value = info.field.get(null);
|
|
||||||
info.tempValue = info.value.toString();
|
|
||||||
} catch (IllegalAccessException ignored) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
loadFromFile();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void initNestedClass(Class<?> config, String category)
|
|
||||||
{
|
|
||||||
for (Field field : config.getFields())
|
|
||||||
{
|
|
||||||
EntryInfo info = new EntryInfo();
|
|
||||||
if (field.isAnnotationPresent(ConfigAnnotations.Entry.class) || field.isAnnotationPresent(ConfigAnnotations.Comment.class) || field.isAnnotationPresent(ConfigAnnotations.ScreenEntry.class))
|
|
||||||
{
|
|
||||||
// If putting in your own mod then put your own check for server sided
|
|
||||||
info.category = category;
|
|
||||||
if (!LodCommonMain.serverSided)
|
|
||||||
initClient(field, info, category);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (field.isAnnotationPresent(ConfigAnnotations.Entry.class))
|
|
||||||
{
|
|
||||||
entryMap.put((!category.isEmpty() ? category + "." : "") + field.getName(), info);
|
|
||||||
info.varClass = field.getType();
|
|
||||||
try
|
|
||||||
{
|
|
||||||
info.defaultValue = field.get(null);
|
|
||||||
}
|
|
||||||
catch (IllegalAccessException ignored) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (field.isAnnotationPresent(ConfigAnnotations.ScreenEntry.class))
|
|
||||||
initNestedClass(field.getType(), (!category.isEmpty() ? category + "." : "") + field.getName());
|
|
||||||
|
|
||||||
// File comment (WILL BE REMOVED SOON)
|
|
||||||
if (field.isAnnotationPresent(ConfigAnnotations.FileComment.class)) {
|
|
||||||
entryMap.put((!category.isEmpty() ? category + "." : "") + field.getName(), info);
|
|
||||||
info.fileComment = true;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
info.value = info.defaultValue = field.get(null);
|
|
||||||
}
|
|
||||||
catch (IllegalAccessException ignored) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
info.field = field;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** This adds the buttons to the queue to be rendered */
|
|
||||||
private static void initClient(Field field, EntryInfo info, String category)
|
|
||||||
{
|
|
||||||
Class<?> fieldClass = field.getType();
|
|
||||||
ConfigAnnotations.Entry entry = field.getAnnotation(ConfigAnnotations.Entry.class);
|
|
||||||
ConfigAnnotations.ScreenEntry screenEntry = field.getAnnotation(ConfigAnnotations.ScreenEntry.class);
|
|
||||||
|
|
||||||
if (entry != null)
|
|
||||||
info.width = entry.width();
|
|
||||||
else if (screenEntry != null)
|
|
||||||
info.width = screenEntry.width();
|
|
||||||
|
|
||||||
if (entry != null)
|
|
||||||
{
|
|
||||||
if (!entry.name().equals(""))
|
|
||||||
info.name = new TranslatableComponent(entry.name());
|
|
||||||
|
|
||||||
|
|
||||||
if (fieldClass == int.class)
|
|
||||||
{
|
|
||||||
// For int
|
|
||||||
textField(info, Integer::parseInt, INTEGER_ONLY_REGEX, entry.minValue(), entry.maxValue(), true);
|
|
||||||
}
|
|
||||||
else if (fieldClass == double.class)
|
|
||||||
{
|
|
||||||
// For double
|
|
||||||
textField(info, Double::parseDouble, DECIMAL_ONLY_REGEX, entry.minValue(), entry.maxValue(), false);
|
|
||||||
}
|
|
||||||
else if (fieldClass == String.class || fieldClass == List.class)
|
|
||||||
{
|
|
||||||
// For string or list
|
|
||||||
info.max = entry.maxValue() == Double.MAX_VALUE ? Integer.MAX_VALUE : (int) entry.maxValue();
|
|
||||||
textField(info, String::length, null, Math.min(entry.minValue(), 0), Math.max(entry.maxValue(), 1), true);
|
|
||||||
}
|
|
||||||
else if (fieldClass == boolean.class)
|
|
||||||
{
|
|
||||||
// For boolean
|
|
||||||
Function<Object, Component> func = value -> new TextComponent((Boolean) value ? "True" : "False").withStyle((Boolean) value ? ChatFormatting.GREEN : ChatFormatting.RED);
|
|
||||||
info.widget = new AbstractMap.SimpleEntry<Button.OnPress, Function<Object, Component>>(button -> {
|
|
||||||
info.value = !(Boolean) info.value;
|
|
||||||
button.setMessage(func.apply(info.value));
|
|
||||||
}, func);
|
|
||||||
}
|
|
||||||
else if (fieldClass.isEnum())
|
|
||||||
{
|
|
||||||
// For enum
|
|
||||||
List<?> values = Arrays.asList(field.getType().getEnumConstants());
|
|
||||||
Function<Object, Component> func = value -> new TranslatableComponent(MOD_NAME + ".config." + "enum." + fieldClass.getSimpleName() + "." + info.value.toString());
|
|
||||||
info.widget = new AbstractMap.SimpleEntry<Button.OnPress, Function<Object, Component>>(button -> {
|
|
||||||
int index = values.indexOf(info.value) + 1;
|
|
||||||
info.value = values.get(index >= values.size() ? 0 : index);
|
|
||||||
button.setMessage(func.apply(info.value));
|
|
||||||
}, func);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (screenEntry != null)
|
|
||||||
{
|
|
||||||
if (!screenEntry.name().equals(""))
|
|
||||||
info.name = new TranslatableComponent(screenEntry.name());
|
|
||||||
|
|
||||||
info.screenButton = true;
|
|
||||||
info.gotoScreen = (!info.category.isEmpty() ? info.category + "." : "") + field.getName();
|
|
||||||
}
|
|
||||||
entries.add(info);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/** creates a text field */
|
|
||||||
private static void textField(EntryInfo info, Function<String, Number> func, Pattern pattern, double minValue, double maxValue, boolean cast)
|
|
||||||
{
|
|
||||||
boolean isNumber = pattern != null;
|
|
||||||
info.widget = (BiFunction<EditBox, Button, Predicate<String>>) (editBox, button) -> stringValue ->
|
|
||||||
{
|
|
||||||
stringValue = stringValue.trim();
|
|
||||||
if (!(stringValue.isEmpty() || !isNumber || pattern.matcher(stringValue).matches()))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
Number value = 0;
|
|
||||||
boolean inLimits = false;
|
|
||||||
info.error = null;
|
|
||||||
if (isNumber && !stringValue.isEmpty() && !stringValue.equals("-") && !stringValue.equals("."))
|
|
||||||
{
|
|
||||||
value = func.apply(stringValue);
|
|
||||||
inLimits = value.doubleValue() >= minValue && value.doubleValue() <= maxValue;
|
|
||||||
info.error = inLimits ? null : new AbstractMap.SimpleEntry<>(editBox, new TextComponent(value.doubleValue() < minValue ?
|
|
||||||
"§cMinimum " + "length" + (cast ? " is " + (int) minValue : " is " + minValue) :
|
|
||||||
"§cMaximum " + "length" + (cast ? " is " + (int) maxValue : " is " + maxValue)));
|
|
||||||
}
|
|
||||||
|
|
||||||
info.tempValue = stringValue;
|
|
||||||
editBox.setTextColor(inLimits ? 0xFFFFFFFF : 0xFFFF7777);
|
|
||||||
info.inLimits = inLimits;
|
|
||||||
button.active = entries.stream().allMatch(e -> e.inLimits);
|
|
||||||
|
|
||||||
|
|
||||||
if (inLimits && info.field.getType() != List.class)
|
|
||||||
{
|
|
||||||
info.value = value;
|
|
||||||
}
|
|
||||||
else if (inLimits)
|
|
||||||
{
|
|
||||||
if (((List<String>) info.value).size() == info.index)
|
|
||||||
((List<String>) info.value).add("");
|
|
||||||
((List<String>) info.value).set(info.index, Arrays.stream(info.tempValue.replace("[", "").replace("]", "").split(", ")).collect(Collectors.toList()).get(0));
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//===============//
|
|
||||||
// File Handling //
|
|
||||||
//===============//
|
|
||||||
|
|
||||||
/** Grabs what is in the config and puts it in modid.toml */
|
|
||||||
public static void saveToFile()
|
|
||||||
{
|
|
||||||
CommentedFileConfig config = CommentedFileConfig.builder(configFilePath.toFile()).build();
|
|
||||||
|
|
||||||
// First try to create a config file
|
|
||||||
try {
|
|
||||||
if (!Files.exists(configFilePath))
|
|
||||||
Files.createFile(configFilePath);
|
|
||||||
}
|
|
||||||
catch (Exception e) {
|
|
||||||
LOGGER.info("Failed creating config file for " + MOD_NAME_READABLE + " at the path [" + configFilePath.toString() + "].");
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
loadFileWithErrorCheck(config);
|
|
||||||
|
|
||||||
|
|
||||||
// Just put this here for the future
|
|
||||||
config.setComment("_Version", " DONT TOUCH THIS, IF YOU DO THEN CONFIG FILE WOULD BREAK");
|
|
||||||
config.set("_Versions", ModInfo.VERSION);
|
|
||||||
|
|
||||||
|
|
||||||
for (EntryInfo info : entries) {
|
|
||||||
if (info.field.isAnnotationPresent(ConfigAnnotations.Entry.class)) {
|
|
||||||
editSingleOption.saveOption(info, config);
|
|
||||||
|
|
||||||
if (editSingleOption.getEntry((info.category.isEmpty() ? "" : info.category + ".") + "_" + info.field.getName()) != null)
|
|
||||||
config.setComment((info.category.isEmpty() ? "" : info.category + ".") + info.field.getName(), String.valueOf(editSingleOption.getEntry((info.category.isEmpty() ? "" : info.category + ".") + "_" + info.field.getName()).defaultValue));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
config.save();
|
|
||||||
config.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Grabs what is in modid.toml and puts it into the config
|
|
||||||
* If the file doesn't exist then it runs saveToFile
|
|
||||||
*/
|
|
||||||
public static void loadFromFile()
|
|
||||||
{
|
|
||||||
CommentedFileConfig config = CommentedFileConfig.builder(configFilePath.toFile()).autosave().build();
|
|
||||||
|
|
||||||
// First checks if the config file was already made
|
|
||||||
if (!Files.exists(configFilePath)) {
|
|
||||||
LOGGER.info("Config file not found for " + MOD_NAME_READABLE + ". Creating config...");
|
|
||||||
saveToFile();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
loadFileWithErrorCheck(config);
|
|
||||||
|
|
||||||
|
|
||||||
// Just put this here for the future
|
|
||||||
config.setComment("_Version", " DONT TOUCH THIS, IF YOU DO THEN CONFIG FILE WOULD BREAK");
|
|
||||||
config.set("_Versions", ModInfo.VERSION);
|
|
||||||
|
|
||||||
|
|
||||||
// Puts everything into its variable
|
|
||||||
for (EntryInfo info : entries) {
|
|
||||||
if (info.field.isAnnotationPresent(ConfigAnnotations.Entry.class)) {
|
|
||||||
editSingleOption.loadOption(info, config);
|
|
||||||
|
|
||||||
// File comments (WILL REMOVE SOON)
|
|
||||||
if (editSingleOption.getEntry((info.category.isEmpty() ? "" : info.category + ".") + "_" + info.field.getName()) != null)
|
|
||||||
config.setComment((info.category.isEmpty() ? "" : info.category + ".") + info.field.getName(), String.valueOf(editSingleOption.getEntry((info.category.isEmpty() ? "" : info.category + ".") + "_" + info.field.getName()).defaultValue));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
config.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class editSingleOption {
|
|
||||||
/** Get the entry info of an item using its string name */
|
|
||||||
public static EntryInfo getEntry(String name)
|
|
||||||
{
|
|
||||||
return entryMap.get(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Save a single item using its string name */
|
|
||||||
public static void saveOption(String name)
|
|
||||||
{
|
|
||||||
saveOption(entryMap.get(name));
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Saves a single item using entry info */
|
|
||||||
public static void saveOption(EntryInfo info)
|
|
||||||
{
|
|
||||||
CommentedFileConfig config = CommentedFileConfig.builder(configFilePath.toFile()).autosave().build();
|
|
||||||
|
|
||||||
loadFileWithErrorCheck(config);
|
|
||||||
|
|
||||||
saveOption(info, config);
|
|
||||||
|
|
||||||
config.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Saves a single item using its entry info and its config builder */
|
|
||||||
public static void saveOption(EntryInfo info, CommentedFileConfig config)
|
|
||||||
{
|
|
||||||
config.set((info.category.isEmpty() ? "" : info.category + ".") + info.field.getName(), info.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Load a single item using its string name */
|
|
||||||
public static void loadOption(String name)
|
|
||||||
{
|
|
||||||
loadOption(entryMap.get(name));
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Load a single item using entry info */
|
|
||||||
public static void loadOption(EntryInfo info)
|
|
||||||
{
|
|
||||||
CommentedFileConfig config = CommentedFileConfig.builder(configFilePath.toFile()).autosave().build();
|
|
||||||
|
|
||||||
loadFileWithErrorCheck(config);
|
|
||||||
|
|
||||||
loadOption(info, config);
|
|
||||||
|
|
||||||
config.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Loads a single item using its entry info and its config builder */
|
|
||||||
public static void loadOption(EntryInfo info, CommentedFileConfig config)
|
|
||||||
{
|
|
||||||
String itemPath = (info.category.isEmpty() ? "" : info.category + ".") + info.field.getName();
|
|
||||||
if (config.contains(itemPath)) {
|
|
||||||
if (info.field.getType().isEnum())
|
|
||||||
info.value = config.getEnum(itemPath, info.varClass);
|
|
||||||
else
|
|
||||||
info.value = config.get(itemPath);
|
|
||||||
} else
|
|
||||||
config.set(itemPath, info.value);
|
|
||||||
|
|
||||||
try {
|
|
||||||
info.field.set(null, info.value);
|
|
||||||
} catch (IllegalAccessException ignored) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Dose config.load(); but with error checking to avoid crashes */
|
|
||||||
public static void loadFileWithErrorCheck(CommentedFileConfig config) {
|
|
||||||
try {
|
|
||||||
config.load();
|
|
||||||
} catch (Exception e) {
|
|
||||||
LOGGER.info("Error loading config for " + MOD_NAME_READABLE + " at the path [" + configFilePath.toString() + "].");
|
|
||||||
LOGGER.info("Creating a new config...");
|
|
||||||
try {
|
|
||||||
Files.deleteIfExists(configFilePath);
|
|
||||||
saveToFile();
|
|
||||||
} catch (Exception f) {
|
|
||||||
LOGGER.info("Failed creating config file for " + MOD_NAME_READABLE + " at the path [" + configFilePath.toString() + "].");
|
|
||||||
f.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//==============//
|
|
||||||
// GUI handling //
|
|
||||||
//==============//
|
|
||||||
|
|
||||||
public static Screen getScreen(Screen parent, String category)
|
|
||||||
{
|
|
||||||
return new ConfigScreen(parent, category);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class ConfigScreen extends Screen
|
|
||||||
{
|
|
||||||
protected ConfigScreen(Screen parent, String category)
|
|
||||||
{
|
|
||||||
super(new TranslatableComponent(
|
|
||||||
I18n.exists(MOD_NAME + ".config" + (category.isEmpty()? "." + category : "") + ".title") ?
|
|
||||||
MOD_NAME + ".config.title" :
|
|
||||||
MOD_NAME + ".config" + (category.isEmpty() ? "" : "." + category) + ".title")
|
|
||||||
);
|
|
||||||
this.parent = parent;
|
|
||||||
this.category = category;
|
|
||||||
this.translationPrefix = MOD_NAME + ".config.";
|
|
||||||
}
|
|
||||||
|
|
||||||
private final String translationPrefix;
|
|
||||||
private final Screen parent;
|
|
||||||
private final String category;
|
|
||||||
private ConfigListWidget list;
|
|
||||||
private boolean reload = false;
|
|
||||||
|
|
||||||
// Real Time config update //
|
|
||||||
@Override
|
|
||||||
public void tick()
|
|
||||||
{
|
|
||||||
super.tick();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/** When you close it, it goes to the previous screen and saves */
|
|
||||||
@Override
|
|
||||||
public void onClose()
|
|
||||||
{
|
|
||||||
saveToFile();
|
|
||||||
Objects.requireNonNull(minecraft).setScreen(this.parent);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void init()
|
|
||||||
{
|
|
||||||
super.init();
|
|
||||||
if (!reload)
|
|
||||||
loadFromFile();
|
|
||||||
|
|
||||||
// addRenderableWidget in 1.17 and over
|
|
||||||
// addButton in 1.16 and below
|
|
||||||
this.addRenderableWidget(new Button(this.width / 2 - 154, this.height - 28, 150, 20, CommonComponents.GUI_CANCEL, button -> {
|
|
||||||
loadFromFile();
|
|
||||||
Objects.requireNonNull(minecraft).setScreen(parent);
|
|
||||||
}));
|
|
||||||
|
|
||||||
Button done = this.addRenderableWidget(new Button(this.width / 2 + 4, this.height - 28, 150, 20, CommonComponents.GUI_DONE, (button) -> {
|
|
||||||
saveToFile();
|
|
||||||
Objects.requireNonNull(minecraft).setScreen(parent);
|
|
||||||
}));
|
|
||||||
|
|
||||||
this.list = new ConfigListWidget(this.minecraft, this.width * 2, this.height, 32, this.height - 32, 25);
|
|
||||||
if (this.minecraft != null && this.minecraft.level != null)
|
|
||||||
this.list.setRenderBackground(false);
|
|
||||||
this.addWidget(this.list);
|
|
||||||
for (EntryInfo info : entries)
|
|
||||||
{
|
|
||||||
if (info.category.matches(category) && !info.hideOption)
|
|
||||||
{
|
|
||||||
TranslatableComponent name = (info.name == null ? new TranslatableComponent(translationPrefix + (!info.category.isEmpty() ? info.category + "." : "") + info.field.getName()) : info.name);
|
|
||||||
Button resetButton = new Button(this.width - ConfigScreenConfigs.SpaceFromRightScreen - info.width - ConfigScreenConfigs.ButtonWidthSpacing - ConfigScreenConfigs.ResetButtonWidth, 0, ConfigScreenConfigs.ResetButtonWidth, 20, new TextComponent("Reset").withStyle(ChatFormatting.RED), (button -> {
|
|
||||||
info.value = info.defaultValue;
|
|
||||||
info.tempValue = info.defaultValue.toString();
|
|
||||||
info.index = 0;
|
|
||||||
this.reload = true;
|
|
||||||
Objects.requireNonNull(minecraft).setScreen(this);
|
|
||||||
}));
|
|
||||||
|
|
||||||
if (info.widget instanceof Map.Entry)
|
|
||||||
{
|
|
||||||
Map.Entry<Button.OnPress, Function<Object, Component>> widget = (Map.Entry<Button.OnPress, Function<Object, Component>>) info.widget;
|
|
||||||
if (info.field.getType().isEnum())
|
|
||||||
widget.setValue(value -> new TranslatableComponent(translationPrefix + "enum." + info.field.getType().getSimpleName() + "." + info.value.toString()));
|
|
||||||
this.list.addButton(new Button(this.width - info.width - ConfigScreenConfigs.SpaceFromRightScreen, 0, info.width, 20, widget.getValue().apply(info.value), widget.getKey()), resetButton, null, name);
|
|
||||||
}
|
|
||||||
else if (info.field.getType() == List.class)
|
|
||||||
{
|
|
||||||
if (!reload)
|
|
||||||
info.index = 0;
|
|
||||||
EditBox widget = new EditBox(font, this.width - info.width - ConfigScreenConfigs.SpaceFromRightScreen, 0, info.width, 20, null);
|
|
||||||
widget.setMaxLength(info.width);
|
|
||||||
if (info.index < ((List<String>) info.value).size())
|
|
||||||
widget.insertText((String.valueOf(((List<String>) info.value).get(info.index))));
|
|
||||||
else
|
|
||||||
widget.insertText("");
|
|
||||||
Predicate<String> processor = ((BiFunction<EditBox, Button, Predicate<String>>) info.widget).apply(widget, done);
|
|
||||||
widget.setFilter(processor);
|
|
||||||
resetButton.setWidth(20);
|
|
||||||
resetButton.setMessage(new TextComponent("R").withStyle(ChatFormatting.RED));
|
|
||||||
Button cycleButton = new Button(this.width - 185, 0, 20, 20, new TextComponent(String.valueOf(info.index)).withStyle(ChatFormatting.GOLD), (button -> {
|
|
||||||
((List<String>) info.value).remove("");
|
|
||||||
this.reload = true;
|
|
||||||
info.index = info.index + 1;
|
|
||||||
if (info.index > ((List<String>) info.value).size())
|
|
||||||
info.index = 0;
|
|
||||||
Objects.requireNonNull(minecraft).setScreen(this);
|
|
||||||
}));
|
|
||||||
this.list.addButton(widget, resetButton, cycleButton, name);
|
|
||||||
}
|
|
||||||
else if (info.widget != null)
|
|
||||||
{
|
|
||||||
EditBox widget = new EditBox(font, this.width - info.width - ConfigScreenConfigs.SpaceFromRightScreen + 2, 0, info.width - 4, 20, null);
|
|
||||||
widget.setMaxLength(info.width);
|
|
||||||
widget.insertText(String.valueOf(info.value));
|
|
||||||
Predicate<String> processor = ((BiFunction<EditBox, Button, Predicate<String>>) info.widget).apply(widget, done);
|
|
||||||
widget.setFilter(processor);
|
|
||||||
this.list.addButton(widget, resetButton, null, name);
|
|
||||||
}
|
|
||||||
else if (info.screenButton)
|
|
||||||
{
|
|
||||||
Button widget = new Button(this.width / 2 - info.width, this.height - 28, info.width * 2, 20, name, (button -> {
|
|
||||||
saveToFile();
|
|
||||||
Objects.requireNonNull(minecraft).setScreen(ConfigGui.getScreen(this, info.gotoScreen));
|
|
||||||
}));
|
|
||||||
this.list.addButton(widget, null, null, null);
|
|
||||||
}
|
|
||||||
else if (!info.fileComment)
|
|
||||||
{
|
|
||||||
this.list.addButton(null, null, null, name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void render(PoseStack matrices, int mouseX, int mouseY, float delta)
|
|
||||||
{
|
|
||||||
this.renderBackground(matrices); // Renders background
|
|
||||||
this.list.render(matrices, mouseX, mouseY, delta); // Render buttons
|
|
||||||
drawCenteredString(matrices, font, title, width / 2, 15, 0xFFFFFF); // Render title
|
|
||||||
|
|
||||||
// Render the tooltip only if it can find a tooltip in the language file
|
|
||||||
for (EntryInfo info : entries) {
|
|
||||||
if (info.category.matches(category) && !info.hideOption) {
|
|
||||||
if (list.getHoveredButton(mouseX,mouseY).isPresent()) {
|
|
||||||
AbstractWidget buttonWidget = list.getHoveredButton(mouseX,mouseY).get();
|
|
||||||
Component text = ButtonEntry.buttonsWithText.get(buttonWidget);
|
|
||||||
TranslatableComponent name = new TranslatableComponent(this.translationPrefix + (info.category.isEmpty() ? "" : info.category + ".") + info.field.getName());
|
|
||||||
String key = translationPrefix + (info.category.isEmpty() ? "" : info.category + ".") + info.field.getName() + ".@tooltip";
|
|
||||||
|
|
||||||
if (info.error != null && text.equals(name)) renderTooltip(matrices, (Component) info.error.getValue(), mouseX, mouseY);
|
|
||||||
else if (I18n.exists(key) && (text != null && text.equals(name))) {
|
|
||||||
List<Component> list = new ArrayList<>();
|
|
||||||
for (String str : I18n.get(key).split("\n"))
|
|
||||||
list.add(new TextComponent(str));
|
|
||||||
renderComponentTooltip(matrices, list, mouseX, mouseY);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
super.render(matrices, mouseX, mouseY, delta);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static class ConfigListWidget extends ContainerObjectSelectionList<ButtonEntry>
|
|
||||||
{
|
|
||||||
Font textRenderer;
|
|
||||||
|
|
||||||
public ConfigListWidget(Minecraft minecraftClient, int i, int j, int k, int l, int m)
|
|
||||||
{
|
|
||||||
super(minecraftClient, i, j, k, l, m);
|
|
||||||
this.centerListVertically = false;
|
|
||||||
textRenderer = minecraftClient.font;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addButton(AbstractWidget button, AbstractWidget resetButton, AbstractWidget indexButton, Component text)
|
|
||||||
{
|
|
||||||
this.addEntry(ButtonEntry.create(button, text, resetButton, indexButton));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getRowWidth()
|
|
||||||
{
|
|
||||||
return 10000;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Optional<AbstractWidget> getHoveredButton(double mouseX, double mouseY)
|
|
||||||
{
|
|
||||||
for (ButtonEntry buttonEntry : this.children())
|
|
||||||
{
|
|
||||||
if (buttonEntry.button != null && buttonEntry.button.isMouseOver(mouseX, mouseY))
|
|
||||||
{
|
|
||||||
return Optional.of(buttonEntry.button);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return Optional.empty();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static class ButtonEntry extends ContainerObjectSelectionList.Entry<ButtonEntry>
|
|
||||||
{
|
|
||||||
private static final Font textRenderer = Minecraft.getInstance().font;
|
|
||||||
public final AbstractWidget button;
|
|
||||||
private final AbstractWidget resetButton;
|
|
||||||
private final AbstractWidget indexButton;
|
|
||||||
private final Component text;
|
|
||||||
private final List<AbstractWidget> children = new ArrayList<>();
|
|
||||||
public static final Map<AbstractWidget, Component> buttonsWithText = new HashMap<>();
|
|
||||||
|
|
||||||
private ButtonEntry(AbstractWidget button, Component text, AbstractWidget resetButton, AbstractWidget indexButton)
|
|
||||||
{
|
|
||||||
buttonsWithText.put(button, text);
|
|
||||||
this.button = button;
|
|
||||||
this.resetButton = resetButton;
|
|
||||||
this.text = text;
|
|
||||||
this.indexButton = indexButton;
|
|
||||||
if (button != null)
|
|
||||||
children.add(button);
|
|
||||||
if (resetButton != null)
|
|
||||||
children.add(resetButton);
|
|
||||||
if (indexButton != null)
|
|
||||||
children.add(indexButton);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ButtonEntry create(AbstractWidget button, Component text, AbstractWidget resetButton, AbstractWidget indexButton)
|
|
||||||
{
|
|
||||||
return new ButtonEntry(button, text, resetButton, indexButton);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void render(PoseStack matrices, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean hovered, float tickDelta)
|
|
||||||
{
|
|
||||||
if (button != null)
|
|
||||||
{
|
|
||||||
button.y = y;
|
|
||||||
button.render(matrices, mouseX, mouseY, tickDelta);
|
|
||||||
}
|
|
||||||
if (resetButton != null)
|
|
||||||
{
|
|
||||||
resetButton.y = y;
|
|
||||||
resetButton.render(matrices, mouseX, mouseY, tickDelta);
|
|
||||||
}
|
|
||||||
if (indexButton != null)
|
|
||||||
{
|
|
||||||
indexButton.y = y;
|
|
||||||
indexButton.render(matrices, mouseX, mouseY, tickDelta);
|
|
||||||
}
|
|
||||||
if (text != null && (!text.getString().contains("spacer") || button != null))
|
|
||||||
GuiComponent.drawString(matrices, textRenderer, text, 12, y + 5, 0xFFFFFF);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<? extends GuiEventListener> children()
|
|
||||||
{
|
|
||||||
return children;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Only for 1.17 and over
|
|
||||||
// Remove in 1.16 and below
|
|
||||||
@Override
|
|
||||||
public List<? extends NarratableEntry> narratables()
|
|
||||||
{
|
|
||||||
return children;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-786
@@ -1,786 +0,0 @@
|
|||||||
package com.seibel.lod.common.wrappers.config;
|
|
||||||
|
|
||||||
import com.seibel.lod.core.enums.config.*;
|
|
||||||
import com.seibel.lod.core.enums.rendering.*;
|
|
||||||
import com.seibel.lod.core.wrapperInterfaces.config.ILodConfigWrapperSingleton;
|
|
||||||
import com.seibel.lod.common.Config;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This holds the config defaults and setters/getters
|
|
||||||
* that should be hooked into the host mod loader (Fabric, Forge, etc.).
|
|
||||||
*
|
|
||||||
* @author James Seibel
|
|
||||||
* @version 11-16-2021
|
|
||||||
*/
|
|
||||||
public class LodConfigWrapperSingleton implements ILodConfigWrapperSingleton
|
|
||||||
{
|
|
||||||
public static final LodConfigWrapperSingleton INSTANCE = new LodConfigWrapperSingleton();
|
|
||||||
|
|
||||||
|
|
||||||
private static final Client client = new Client();
|
|
||||||
@Override
|
|
||||||
public IClient client()
|
|
||||||
{
|
|
||||||
return client;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class Client implements IClient
|
|
||||||
{
|
|
||||||
public final IGraphics graphics;
|
|
||||||
public final IWorldGenerator worldGenerator;
|
|
||||||
public final IMultiplayer multiplayer;
|
|
||||||
public final IAdvanced advanced;
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public IGraphics graphics()
|
|
||||||
{
|
|
||||||
return graphics;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public IWorldGenerator worldGenerator()
|
|
||||||
{
|
|
||||||
return worldGenerator;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public IMultiplayer multiplayer() {
|
|
||||||
return multiplayer;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public IAdvanced advanced()
|
|
||||||
{
|
|
||||||
return advanced;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean getOptionsButton()
|
|
||||||
{
|
|
||||||
return Config.optionsButton;
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public void setOptionsButton(boolean newOptionsButton)
|
|
||||||
{
|
|
||||||
ConfigGui.editSingleOption.getEntry("optionsButton").value = newOptionsButton;
|
|
||||||
ConfigGui.editSingleOption.saveOption("optionsButton");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//================//
|
|
||||||
// Client Configs //
|
|
||||||
//================//
|
|
||||||
public Client()
|
|
||||||
{
|
|
||||||
graphics = new Graphics();
|
|
||||||
worldGenerator = new WorldGenerator();
|
|
||||||
multiplayer = new Multiplayer();
|
|
||||||
advanced = new Advanced();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//==================//
|
|
||||||
// Graphics Configs //
|
|
||||||
//==================//
|
|
||||||
public static class Graphics implements IGraphics
|
|
||||||
{
|
|
||||||
public final IQuality quality;
|
|
||||||
public final IFogQuality fogQuality;
|
|
||||||
public final IAdvancedGraphics advancedGraphics;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public IQuality quality()
|
|
||||||
{
|
|
||||||
return quality;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public IFogQuality fogQuality()
|
|
||||||
{
|
|
||||||
return fogQuality;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public IAdvancedGraphics advancedGraphics()
|
|
||||||
{
|
|
||||||
return advancedGraphics;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Graphics()
|
|
||||||
{
|
|
||||||
quality = new Quality();
|
|
||||||
fogQuality = new FogQuality();
|
|
||||||
advancedGraphics = new AdvancedGraphics();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public static class Quality implements IQuality
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public HorizontalResolution getDrawResolution()
|
|
||||||
{
|
|
||||||
return Config.Client.Graphics.Quality.drawResolution;
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public void setDrawResolution(HorizontalResolution newHorizontalResolution)
|
|
||||||
{
|
|
||||||
ConfigGui.editSingleOption.getEntry("client.graphics.quality.drawResolution").value = newHorizontalResolution;
|
|
||||||
ConfigGui.editSingleOption.saveOption("client.graphics.quality.drawResolution");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getLodChunkRenderDistance()
|
|
||||||
{
|
|
||||||
return Config.Client.Graphics.Quality.lodChunkRenderDistance;
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public void setLodChunkRenderDistance(int newLodChunkRenderDistance)
|
|
||||||
{
|
|
||||||
ConfigGui.editSingleOption.getEntry("client.graphics.quality.lodChunkRenderDistance").value = newLodChunkRenderDistance;
|
|
||||||
ConfigGui.editSingleOption.saveOption("client.graphics.quality.lodChunkRenderDistance");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public VerticalQuality getVerticalQuality()
|
|
||||||
{
|
|
||||||
return Config.Client.Graphics.Quality.verticalQuality;
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public void setVerticalQuality(VerticalQuality newVerticalQuality)
|
|
||||||
{
|
|
||||||
ConfigGui.editSingleOption.getEntry("client.graphics.quality.verticalQuality").value = newVerticalQuality;
|
|
||||||
ConfigGui.editSingleOption.saveOption("client.graphics.quality.verticalQuality");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getHorizontalScale()
|
|
||||||
{
|
|
||||||
return Config.Client.Graphics.Quality.horizontalScale;
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public void setHorizontalScale(int newHorizontalScale)
|
|
||||||
{
|
|
||||||
ConfigGui.editSingleOption.getEntry("client.graphics.quality.horizontalScale").value = newHorizontalScale;
|
|
||||||
ConfigGui.editSingleOption.saveOption("client.graphics.quality.horizontalScale");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public HorizontalQuality getHorizontalQuality()
|
|
||||||
{
|
|
||||||
return Config.Client.Graphics.Quality.horizontalQuality;
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public void setHorizontalQuality(HorizontalQuality newHorizontalQuality)
|
|
||||||
{
|
|
||||||
ConfigGui.editSingleOption.getEntry("client.graphics.quality.horizontalQuality").value = newHorizontalQuality;
|
|
||||||
ConfigGui.editSingleOption.saveOption("client.graphics.quality.horizontalQuality");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public DropoffQuality getDropoffQuality() {
|
|
||||||
return Config.Client.Graphics.Quality.dropoffQuality;
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public void setDropoffQuality(DropoffQuality newDropoffQuality) {
|
|
||||||
ConfigGui.editSingleOption.getEntry("client.graphics.quality.dropoffQuality").value = newDropoffQuality;
|
|
||||||
ConfigGui.editSingleOption.saveOption("client.graphics.quality.dropoffQuality");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getLodBiomeBlending() {
|
|
||||||
return Config.Client.Graphics.Quality.lodBiomeBlending;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setLodBiomeBlending(int newLodBiomeBlending) {
|
|
||||||
ConfigGui.editSingleOption.getEntry("client.graphics.quality.lodBiomeBlending").value = newLodBiomeBlending;
|
|
||||||
ConfigGui.editSingleOption.saveOption("client.graphics.quality.lodBiomeBlending");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public static class FogQuality implements IFogQuality
|
|
||||||
{
|
|
||||||
public final IAdvancedFog advancedFog;
|
|
||||||
|
|
||||||
FogQuality()
|
|
||||||
{
|
|
||||||
advancedFog = new AdvancedFog();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public FogDistance getFogDistance()
|
|
||||||
{
|
|
||||||
return Config.Client.Graphics.FogQuality.fogDistance;
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public void setFogDistance(FogDistance newFogDistance)
|
|
||||||
{
|
|
||||||
ConfigGui.editSingleOption.getEntry("client.graphics.fogQuality.fogDistance").value = newFogDistance;
|
|
||||||
ConfigGui.editSingleOption.saveOption("client.graphics.fogQuality.fogDistance");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public FogDrawMode getFogDrawMode()
|
|
||||||
{
|
|
||||||
return Config.Client.Graphics.FogQuality.fogDrawMode;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setFogDrawMode(FogDrawMode setFogDrawMode)
|
|
||||||
{
|
|
||||||
ConfigGui.editSingleOption.getEntry("client.graphics.fogQuality.fogDrawMode").value = setFogDrawMode;
|
|
||||||
ConfigGui.editSingleOption.saveOption("client.graphics.fogQuality.fogDrawMode");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public FogColorMode getFogColorMode()
|
|
||||||
{
|
|
||||||
return Config.Client.Graphics.FogQuality.fogColorMode;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setFogColorMode(FogColorMode newFogColorMode)
|
|
||||||
{
|
|
||||||
ConfigGui.editSingleOption.getEntry("client.graphics.fogQuality.fogColorMode").value = newFogColorMode;
|
|
||||||
ConfigGui.editSingleOption.saveOption("client.graphics.fogQuality.fogColorMode");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean getDisableVanillaFog()
|
|
||||||
{
|
|
||||||
return Config.Client.Graphics.FogQuality.disableVanillaFog;
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public void setDisableVanillaFog(boolean newDisableVanillaFog)
|
|
||||||
{
|
|
||||||
ConfigGui.editSingleOption.getEntry("client.graphics.fogQuality.disableVanillaFog").value = newDisableVanillaFog;
|
|
||||||
ConfigGui.editSingleOption.saveOption("client.graphics.fogQuality.disableVanillaFog");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public IAdvancedFog advancedFog() {
|
|
||||||
return advancedFog;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class AdvancedFog implements IAdvancedFog {
|
|
||||||
public final IHeightFog heightFog;
|
|
||||||
|
|
||||||
public AdvancedFog() {
|
|
||||||
heightFog = new HeightFog();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public double getFarFogStart() {
|
|
||||||
return Config.Client.Graphics.FogQuality.AdvancedFog.farFogStart;
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public double getFarFogEnd() {
|
|
||||||
return Config.Client.Graphics.FogQuality.AdvancedFog.farFogEnd;
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public double getFarFogMin() {
|
|
||||||
return Config.Client.Graphics.FogQuality.AdvancedFog.farFogMin;
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public double getFarFogMax() {
|
|
||||||
return Config.Client.Graphics.FogQuality.AdvancedFog.farFogMax;
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public FogSetting.FogType getFarFogType() {
|
|
||||||
return Config.Client.Graphics.FogQuality.AdvancedFog.farFogType;
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public double getFarFogDensity() {
|
|
||||||
return Config.Client.Graphics.FogQuality.AdvancedFog.farFogDensity;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setFarFogStart(double newFarFogStart) {
|
|
||||||
ConfigGui.editSingleOption.getEntry("client.graphics.fogQuality.advancedFog.farFogStart").value = newFarFogStart;
|
|
||||||
ConfigGui.editSingleOption.saveOption("client.graphics.fogQuality.advancedFog.farFogStart");
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public void setFarFogEnd(double newFarFogEnd) {
|
|
||||||
ConfigGui.editSingleOption.getEntry("client.graphics.fogQuality.advancedFog.farFogEnd").value = newFarFogEnd;
|
|
||||||
ConfigGui.editSingleOption.saveOption("client.graphics.fogQuality.advancedFog.farFogEnd");
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public void setFarFogMin(double newFarFogMin) {
|
|
||||||
ConfigGui.editSingleOption.getEntry("client.graphics.fogQuality.advancedFog.farFogMin").value = newFarFogMin;
|
|
||||||
ConfigGui.editSingleOption.saveOption("client.graphics.fogQuality.advancedFog.farFogMin");
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public void setFarFogMax(double newFarFogMax) {
|
|
||||||
ConfigGui.editSingleOption.getEntry("client.graphics.fogQuality.advancedFog.farFogMax").value = newFarFogMax;
|
|
||||||
ConfigGui.editSingleOption.saveOption("client.graphics.fogQuality.advancedFog.farFogMax");
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public void setFarFogType(FogSetting.FogType newFarFogType) {
|
|
||||||
ConfigGui.editSingleOption.getEntry("client.graphics.fogQuality.advancedFog.farFogType").value = newFarFogType;
|
|
||||||
ConfigGui.editSingleOption.saveOption("client.graphics.fogQuality.advancedFog.farFogType");
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public void setFarFogDensity(double newFarFogDensity) {
|
|
||||||
ConfigGui.editSingleOption.getEntry("client.graphics.fogQuality.advancedFog.farFogDensity").value = newFarFogDensity;
|
|
||||||
ConfigGui.editSingleOption.saveOption("client.graphics.fogQuality.advancedFog.farFogDensity");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public IHeightFog heightFog() {
|
|
||||||
return heightFog;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class HeightFog implements IHeightFog {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public HeightFogMixMode getHeightFogMixMode() {
|
|
||||||
return Config.Client.Graphics.FogQuality.AdvancedFog.heightFog.heightFogMixMode;
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public HeightFogMode getHeightFogMode() {
|
|
||||||
return Config.Client.Graphics.FogQuality.AdvancedFog.heightFog.heightFogMode;
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public double getHeightFogHeight() {
|
|
||||||
return Config.Client.Graphics.FogQuality.AdvancedFog.heightFog.heightFogHeight;
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public double getHeightFogStart() {
|
|
||||||
return Config.Client.Graphics.FogQuality.AdvancedFog.heightFog.heightFogStart;
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public double getHeightFogEnd() {
|
|
||||||
return Config.Client.Graphics.FogQuality.AdvancedFog.heightFog.heightFogEnd;
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public double getHeightFogMin() {
|
|
||||||
return Config.Client.Graphics.FogQuality.AdvancedFog.heightFog.heightFogMin;
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public double getHeightFogMax() {
|
|
||||||
return Config.Client.Graphics.FogQuality.AdvancedFog.heightFog.heightFogMax;
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public FogSetting.FogType getHeightFogType() {
|
|
||||||
return Config.Client.Graphics.FogQuality.AdvancedFog.heightFog.heightFogType;
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public double getHeightFogDensity() {
|
|
||||||
return Config.Client.Graphics.FogQuality.AdvancedFog.heightFog.heightFogDensity;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setHeightFogMixMode(HeightFogMixMode newHeightFogMixMode) {
|
|
||||||
ConfigGui.editSingleOption.getEntry("client.graphics.fogQuality.advancedFog.heightFog.heightFogMixMode").value = newHeightFogMixMode;
|
|
||||||
ConfigGui.editSingleOption.saveOption("client.graphics.fogQuality.advancedFog.heightFog.heightFogMixMode");
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public void setHeightFogMode(HeightFogMode newHeightFogMode) {
|
|
||||||
ConfigGui.editSingleOption.getEntry("client.graphics.fogQuality.advancedFog.heightFog.heightFogMode").value = newHeightFogMode;
|
|
||||||
ConfigGui.editSingleOption.saveOption("client.graphics.fogQuality.advancedFog.heightFog.heightFogMode");
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public void setHeightFogHeight(double newHeightFogHeight) {
|
|
||||||
ConfigGui.editSingleOption.getEntry("client.graphics.fogQuality.advancedFog.heightFog.heightFogHeight").value = newHeightFogHeight;
|
|
||||||
ConfigGui.editSingleOption.saveOption("client.graphics.fogQuality.advancedFog.heightFog.heightFogHeight");
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public void setHeightFogStart(double newHeightFogStart) {
|
|
||||||
ConfigGui.editSingleOption.getEntry("client.graphics.fogQuality.advancedFog.heightFog.heightFogStart").value = newHeightFogStart;
|
|
||||||
ConfigGui.editSingleOption.saveOption("client.graphics.fogQuality.advancedFog.heightFog.heightFogStart");
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public void setHeightFogEnd(double newHeightFogEnd) {
|
|
||||||
ConfigGui.editSingleOption.getEntry("client.graphics.fogQuality.advancedFog.heightFog.heightFogEnd").value = newHeightFogEnd;
|
|
||||||
ConfigGui.editSingleOption.saveOption("client.graphics.fogQuality.advancedFog.heightFog.heightFogEnd");
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public void setHeightFogMin(double newHeightFogMin) {
|
|
||||||
ConfigGui.editSingleOption.getEntry("client.graphics.fogQuality.advancedFog.heightFog.heightFogMin").value = newHeightFogMin;
|
|
||||||
ConfigGui.editSingleOption.saveOption("client.graphics.fogQuality.advancedFog.heightFog.heightFogMin");
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public void setHeightFogMax(double newHeightFogMax) {
|
|
||||||
ConfigGui.editSingleOption.getEntry("client.graphics.fogQuality.advancedFog.heightFog.heightFogMax").value = newHeightFogMax;
|
|
||||||
ConfigGui.editSingleOption.saveOption("client.graphics.fogQuality.advancedFog.heightFog.heightFogMax");
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public void setHeightFogType(FogSetting.FogType newHeightFogType) {
|
|
||||||
ConfigGui.editSingleOption.getEntry("client.graphics.fogQuality.advancedFog.heightFog.heightFogType").value = newHeightFogType;
|
|
||||||
ConfigGui.editSingleOption.saveOption("client.graphics.fogQuality.advancedFog.heightFog.heightFogType");
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public void setHeightFogDensity(double newHeightFogDensity) {
|
|
||||||
ConfigGui.editSingleOption.getEntry("client.graphics.fogQuality.advancedFog.heightFog.heightFogDensity").value = newHeightFogDensity;
|
|
||||||
ConfigGui.editSingleOption.saveOption("client.graphics.fogQuality.advancedFog.heightFog.heightFogDensity");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public static class AdvancedGraphics implements IAdvancedGraphics
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public boolean getDisableDirectionalCulling()
|
|
||||||
{
|
|
||||||
return Config.Client.Graphics.AdvancedGraphics.disableDirectionalCulling;
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public void setDisableDirectionalCulling(boolean newDisableDirectionalCulling)
|
|
||||||
{
|
|
||||||
ConfigGui.editSingleOption.getEntry("client.graphics.advancedGraphics.disableDirectionalCulling").value = newDisableDirectionalCulling;
|
|
||||||
ConfigGui.editSingleOption.saveOption("client.graphics.advancedGraphics.disableDirectionalCulling");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public VanillaOverdraw getVanillaOverdraw()
|
|
||||||
{
|
|
||||||
return Config.Client.Graphics.AdvancedGraphics.vanillaOverdraw;
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public void setVanillaOverdraw(VanillaOverdraw newVanillaOverdraw)
|
|
||||||
{
|
|
||||||
ConfigGui.editSingleOption.getEntry("client.graphics.advancedGraphics.vanillaOverdraw").value = newVanillaOverdraw;
|
|
||||||
ConfigGui.editSingleOption.saveOption("client.graphics.advancedGraphics.vanillaOverdraw");
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
@Override
|
|
||||||
public int getBacksideCullingRange()
|
|
||||||
{
|
|
||||||
return Config.Client.Graphics.AdvancedGraphics.backsideCullingRange;
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public void setBacksideCullingRange(int newBacksideCullingRange)
|
|
||||||
{
|
|
||||||
ConfigGui.editSingleOption.getEntry("client.graphics.advancedGraphics.backsideCullingRange").value = newBacksideCullingRange;
|
|
||||||
ConfigGui.editSingleOption.saveOption("client.graphics.advancedGraphics.backsideCullingRange");
|
|
||||||
}*/
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean getUseExtendedNearClipPlane()
|
|
||||||
{
|
|
||||||
return Config.Client.Graphics.AdvancedGraphics.useExtendedNearClipPlane;
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public void setUseExtendedNearClipPlane(boolean newUseExtendedNearClipPlane)
|
|
||||||
{
|
|
||||||
ConfigGui.editSingleOption.getEntry("client.graphics.advancedGraphics.useExtendedNearClipPlane").value = newUseExtendedNearClipPlane;
|
|
||||||
ConfigGui.editSingleOption.saveOption("client.graphics.advancedGraphics.useExtendedNearClipPlane");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public double getBrightnessMultiplier()
|
|
||||||
{
|
|
||||||
return Config.Client.Graphics.AdvancedGraphics.brightnessMultiplier;
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public void setBrightnessMultiplier(double newBrightnessMultiplier)
|
|
||||||
{
|
|
||||||
ConfigGui.editSingleOption.getEntry("client.graphics.advancedGraphics.brightnessMultiplier").value = newBrightnessMultiplier;
|
|
||||||
ConfigGui.editSingleOption.saveOption("client.graphics.advancedGraphics.brightnessMultiplier");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public double getSaturationMultiplier()
|
|
||||||
{
|
|
||||||
return Config.Client.Graphics.AdvancedGraphics.saturationMultiplier;
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public void setSaturationMultiplier(double newSaturationMultiplier)
|
|
||||||
{
|
|
||||||
ConfigGui.editSingleOption.getEntry("client.graphics.advancedGraphics.saturationMultiplier").value = newSaturationMultiplier;
|
|
||||||
ConfigGui.editSingleOption.saveOption("client.graphics.advancedGraphics.saturationMultiplier");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//========================//
|
|
||||||
// WorldGenerator Configs //
|
|
||||||
//========================//
|
|
||||||
public static class WorldGenerator implements IWorldGenerator
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public GenerationPriority getGenerationPriority()
|
|
||||||
{
|
|
||||||
return Config.Client.WorldGenerator.generationPriority;
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public void setGenerationPriority(GenerationPriority newGenerationPriority)
|
|
||||||
{
|
|
||||||
ConfigGui.editSingleOption.getEntry("client.worldGenerator.generationPriority").value = newGenerationPriority;
|
|
||||||
ConfigGui.editSingleOption.saveOption("client.worldGenerator.generationPriority");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public DistanceGenerationMode getDistanceGenerationMode()
|
|
||||||
{
|
|
||||||
return Config.Client.WorldGenerator.distanceGenerationMode;
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public void setDistanceGenerationMode(DistanceGenerationMode newDistanceGenerationMode)
|
|
||||||
{
|
|
||||||
ConfigGui.editSingleOption.getEntry("client.worldGenerator.distanceGenerationMode").value = newDistanceGenerationMode;
|
|
||||||
ConfigGui.editSingleOption.saveOption("client.worldGenerator.distanceGenerationMode");
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
@Override
|
|
||||||
public boolean getAllowUnstableFeatureGeneration()
|
|
||||||
{
|
|
||||||
return Config.Client.WorldGenerator.allowUnstableFeatureGeneration;
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public void setAllowUnstableFeatureGeneration(boolean newAllowUnstableFeatureGeneration)
|
|
||||||
{
|
|
||||||
ConfigGui.editSingleOption.getEntry("client.worldGenerator.allowUnstableFeatureGeneration").value = newAllowUnstableFeatureGeneration;
|
|
||||||
ConfigGui.editSingleOption.saveOption("client.worldGenerator.allowUnstableFeatureGeneration");
|
|
||||||
}*/
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BlocksToAvoid getBlocksToAvoid()
|
|
||||||
{
|
|
||||||
return Config.Client.WorldGenerator.blocksToAvoid;
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public void setBlockToAvoid(BlocksToAvoid newBlockToAvoid)
|
|
||||||
{
|
|
||||||
ConfigGui.editSingleOption.getEntry("client.worldGenerator.blocksToAvoid").value = newBlockToAvoid;
|
|
||||||
ConfigGui.editSingleOption.saveOption("client.worldGenerator.blocksToAvoid");
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public boolean getEnableDistantGeneration()
|
|
||||||
{
|
|
||||||
return (boolean) ConfigGui.editSingleOption.getEntry("client.worldGenerator.enableDistantGeneration").value;
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public void setEnableDistantGeneration(boolean newEnableDistantGeneration)
|
|
||||||
{
|
|
||||||
ConfigGui.editSingleOption.getEntry("client.worldGenerator.enableDistantGeneration").value = newEnableDistantGeneration;
|
|
||||||
ConfigGui.editSingleOption.saveOption("client.worldGenerator.enableDistantGeneration");
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public LightGenerationMode getLightGenerationMode()
|
|
||||||
{
|
|
||||||
return Config.Client.WorldGenerator.lightGenerationMode;
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public void setLightGenerationMode(LightGenerationMode newLightGenerationMode)
|
|
||||||
{
|
|
||||||
ConfigGui.editSingleOption.getEntry("client.worldGenerator.lightGenerationMode").value = newLightGenerationMode;
|
|
||||||
ConfigGui.editSingleOption.saveOption("client.worldGenerator.lightGenerationMode");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//=====================//
|
|
||||||
// Multiplayer Configs //
|
|
||||||
//=====================//
|
|
||||||
public static class Multiplayer implements IMultiplayer
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public ServerFolderNameMode getServerFolderNameMode()
|
|
||||||
{
|
|
||||||
return Config.Client.Multiplayer.serverFolderNameMode;
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public void setServerFolderNameMode(ServerFolderNameMode newServerFolderNameMode)
|
|
||||||
{
|
|
||||||
ConfigGui.editSingleOption.getEntry("client.multiplayer.serverFolderNameMode").value = newServerFolderNameMode;
|
|
||||||
ConfigGui.editSingleOption.saveOption("client.multiplayer.serverFolderNameMode");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public double getMultiDimensionRequiredSimilarity()
|
|
||||||
{
|
|
||||||
return Config.Client.Multiplayer.multiDimensionRequiredSimilarity;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setMultiDimensionRequiredSimilarity(double newMultiDimensionMinimumSimilarityPercent)
|
|
||||||
{
|
|
||||||
ConfigGui.editSingleOption.getEntry("client.multiplayer.multiDimensionMinimumSimilarityPercent").value = newMultiDimensionMinimumSimilarityPercent;
|
|
||||||
ConfigGui.editSingleOption.saveOption("client.multiplayer.multiDimensionMinimumSimilarityPercent");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//============================//
|
|
||||||
// AdvancedModOptions Configs //
|
|
||||||
//============================//
|
|
||||||
public static class Advanced implements IAdvanced
|
|
||||||
{
|
|
||||||
public final IThreading threading;
|
|
||||||
public final IDebugging debugging;
|
|
||||||
public final IBuffers buffers;
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public IThreading threading()
|
|
||||||
{
|
|
||||||
return threading;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public IDebugging debugging()
|
|
||||||
{
|
|
||||||
return debugging;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public IBuffers buffers()
|
|
||||||
{
|
|
||||||
return buffers;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public Advanced()
|
|
||||||
{
|
|
||||||
threading = new Threading();
|
|
||||||
debugging = new Debugging();
|
|
||||||
buffers = new Buffers();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class Threading implements IThreading
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public int getNumberOfWorldGenerationThreads()
|
|
||||||
{
|
|
||||||
return Config.Client.Advanced.Threading.numberOfWorldGenerationThreads;
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public void setNumberOfWorldGenerationThreads(int newNumberOfWorldGenerationThreads)
|
|
||||||
{
|
|
||||||
ConfigGui.editSingleOption.getEntry("client.advanced.threading.numberOfWorldGenerationThreads").value = newNumberOfWorldGenerationThreads;
|
|
||||||
ConfigGui.editSingleOption.saveOption("client.advanced.threading.numberOfWorldGenerationThreads");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getNumberOfBufferBuilderThreads()
|
|
||||||
{
|
|
||||||
return Config.Client.Advanced.Threading.numberOfBufferBuilderThreads;
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public void setNumberOfBufferBuilderThreads(int newNumberOfWorldBuilderThreads)
|
|
||||||
{
|
|
||||||
ConfigGui.editSingleOption.getEntry("client.advanced.threading.numberOfBufferBuilderThreads").value = newNumberOfWorldBuilderThreads;
|
|
||||||
ConfigGui.editSingleOption.saveOption("client.advanced.threading.numberOfBufferBuilderThreads");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//===============//
|
|
||||||
// Debug Options //
|
|
||||||
//===============//
|
|
||||||
public static class Debugging implements IDebugging
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public boolean getDrawLods()
|
|
||||||
{
|
|
||||||
return (boolean) ConfigGui.editSingleOption.getEntry("client.advanced.debugging.drawLods").value;
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public void setDrawLods(boolean newDrawLods)
|
|
||||||
{
|
|
||||||
ConfigGui.editSingleOption.getEntry("client.advanced.debugging.drawLods").value = newDrawLods;
|
|
||||||
ConfigGui.editSingleOption.saveOption("client.advanced.debugging.drawLods");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public DebugMode getDebugMode()
|
|
||||||
{
|
|
||||||
return (DebugMode) ConfigGui.editSingleOption.getEntry("client.advanced.debugging.debugMode").value;
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public void setDebugMode(DebugMode newDebugMode)
|
|
||||||
{
|
|
||||||
ConfigGui.editSingleOption.getEntry("client.advanced.debugging.debugMode").value = newDebugMode;
|
|
||||||
ConfigGui.editSingleOption.saveOption("client.advanced.debugging.debugMode");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean getDebugKeybindingsEnabled()
|
|
||||||
{
|
|
||||||
return (boolean) ConfigGui.editSingleOption.getEntry("client.advanced.debugging.enableDebugKeybindings").value;
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public void setDebugKeybindingsEnabled(boolean newEnableDebugKeybindings)
|
|
||||||
{
|
|
||||||
ConfigGui.editSingleOption.getEntry("client.advanced.debugging.enableDebugKeybindings").value = newEnableDebugKeybindings;
|
|
||||||
ConfigGui.editSingleOption.saveOption("client.advanced.debugging.enableDebugKeybindings");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public static class Buffers implements IBuffers
|
|
||||||
{
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public GpuUploadMethod getGpuUploadMethod()
|
|
||||||
{
|
|
||||||
return Config.Client.Advanced.Buffers.gpuUploadMethod;
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public void setGpuUploadMethod(GpuUploadMethod newDisableVanillaFog)
|
|
||||||
{
|
|
||||||
ConfigGui.editSingleOption.getEntry("client.advanced.buffers.gpuUploadMethod").value = newDisableVanillaFog;
|
|
||||||
ConfigGui.editSingleOption.saveOption("client.advanced.buffers.gpuUploadMethod");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getGpuUploadPerMegabyteInMilliseconds()
|
|
||||||
{
|
|
||||||
return Config.Client.Advanced.Buffers.gpuUploadPerMegabyteInMilliseconds;
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public void setGpuUploadPerMegabyteInMilliseconds(int newMilliseconds) {
|
|
||||||
ConfigGui.editSingleOption.getEntry("client.advanced.buffers.gpuUploadPerMegabyteInMilliseconds").value = newMilliseconds;
|
|
||||||
ConfigGui.editSingleOption.saveOption("client.advanced.buffers.gpuUploadPerMegabyteInMilliseconds");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BufferRebuildTimes getRebuildTimes()
|
|
||||||
{
|
|
||||||
return Config.Client.Advanced.Buffers.rebuildTimes;
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public void setRebuildTimes(BufferRebuildTimes newBufferRebuildTimes)
|
|
||||||
{
|
|
||||||
ConfigGui.editSingleOption.getEntry("client.advanced.buffers.newBufferRebuildTimes").value = newBufferRebuildTimes;
|
|
||||||
ConfigGui.editSingleOption.saveOption("client.advanced.buffers.newBufferRebuildTimes");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,458 @@
|
|||||||
|
package com.seibel.lod.common.wrappers.gui;
|
||||||
|
|
||||||
|
import java.util.AbstractMap;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.function.BiFunction;
|
||||||
|
import java.util.function.Function;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
// Logger (for debug stuff)
|
||||||
|
|
||||||
|
import com.seibel.lod.core.ModInfo;
|
||||||
|
import com.seibel.lod.core.config.file.ConfigFileHandling;
|
||||||
|
import com.seibel.lod.core.config.types.AbstractConfigType;
|
||||||
|
import com.seibel.lod.core.config.types.ConfigCategory;
|
||||||
|
import com.seibel.lod.core.config.types.ConfigEntry;
|
||||||
|
|
||||||
|
// Uses https://github.com/TheElectronWill/night-config for toml (only for Fabric since Forge already includes this)
|
||||||
|
|
||||||
|
// Gets info from our own mod
|
||||||
|
|
||||||
|
import com.seibel.lod.core.config.*;
|
||||||
|
|
||||||
|
// Minecraft imports
|
||||||
|
|
||||||
|
import com.mojang.blaze3d.vertex.PoseStack;
|
||||||
|
import net.minecraft.ChatFormatting;
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.client.gui.Font;
|
||||||
|
import net.minecraft.client.gui.GuiComponent;
|
||||||
|
import net.minecraft.client.gui.components.AbstractWidget;
|
||||||
|
import net.minecraft.client.gui.components.Button;
|
||||||
|
import net.minecraft.client.gui.components.ContainerObjectSelectionList;
|
||||||
|
import net.minecraft.client.gui.components.EditBox;
|
||||||
|
import net.minecraft.client.gui.components.events.GuiEventListener;
|
||||||
|
import net.minecraft.client.gui.screens.Screen;
|
||||||
|
import net.minecraft.network.chat.CommonComponents;
|
||||||
|
import net.minecraft.network.chat.Component;
|
||||||
|
import net.minecraft.client.resources.language.I18n; // translation
|
||||||
|
#if POST_MC_1_17_1
|
||||||
|
import net.minecraft.client.gui.narration.NarratableEntry;
|
||||||
|
#endif
|
||||||
|
#if PRE_MC_1_19
|
||||||
|
import net.minecraft.network.chat.TextComponent;
|
||||||
|
import net.minecraft.network.chat.TranslatableComponent;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Based upon TinyConfig but is highly modified
|
||||||
|
* https://github.com/Minenash/TinyConfig
|
||||||
|
*
|
||||||
|
* Credits to Motschen
|
||||||
|
*
|
||||||
|
* @author coolGi
|
||||||
|
* @version 4-28-2022
|
||||||
|
*/
|
||||||
|
// FLOATS DONT WORK WITH THIS
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public abstract class ClassicConfigGUI {
|
||||||
|
/*
|
||||||
|
This would be removed later on
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
//==============//
|
||||||
|
// Initializers //
|
||||||
|
//==============//
|
||||||
|
|
||||||
|
// Some regexes to check if an input is valid
|
||||||
|
private static final Pattern INTEGER_ONLY_REGEX = Pattern.compile("(-?[0-9]*)");
|
||||||
|
private static final Pattern DECIMAL_ONLY_REGEX = Pattern.compile("-?([\\d]+\\.?[\\d]*|[\\d]*\\.?[\\d]+|\\.)");
|
||||||
|
|
||||||
|
private static class ConfigScreenConfigs {
|
||||||
|
// This contains all the configs for the configs
|
||||||
|
public static final int SpaceFromRightScreen = 10;
|
||||||
|
public static final int ButtonWidthSpacing = 5;
|
||||||
|
public static final int ResetButtonWidth = 40;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The terribly coded old stuff
|
||||||
|
*/
|
||||||
|
public static class EntryInfo {
|
||||||
|
Object widget;
|
||||||
|
Map.Entry<EditBox, Component> error;
|
||||||
|
String tempValue;
|
||||||
|
int index;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* creates a text field
|
||||||
|
*/
|
||||||
|
private static void textField(AbstractConfigType info, Function<String, Number> func, Pattern pattern, boolean cast) {
|
||||||
|
boolean isNumber = pattern != null;
|
||||||
|
((EntryInfo) info.guiValue).widget = (BiFunction<EditBox, Button, Predicate<String>>) (editBox, button) -> stringValue ->
|
||||||
|
{
|
||||||
|
stringValue = stringValue.trim();
|
||||||
|
if (!(stringValue.isEmpty() || !isNumber || pattern.matcher(stringValue).matches()))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Number value = 0;
|
||||||
|
((EntryInfo) info.guiValue).error = null;
|
||||||
|
if (isNumber && !stringValue.isEmpty() && !stringValue.equals("-") && !stringValue.equals(".")) {
|
||||||
|
value = func.apply(stringValue);
|
||||||
|
#if PRE_MC_1_19
|
||||||
|
((EntryInfo) info.guiValue).error = ((ConfigEntry) info).isValid(value) == 0 ? null : new AbstractMap.SimpleEntry<>(editBox, new TextComponent(((ConfigEntry) info).isValid(value) == -1 ?
|
||||||
|
#else
|
||||||
|
((EntryInfo) info.guiValue).error = ((ConfigEntry) info).isValid(value) == 0 ? null : new AbstractMap.SimpleEntry<>(editBox, Component.translatable(((ConfigEntry) info).isValid(value) == -1 ?
|
||||||
|
#endif
|
||||||
|
"§cMinimum " + "length" + (cast ? " is " + (int) ((ConfigEntry) info).getMin() : " is " + ((ConfigEntry) info).getMin()) :
|
||||||
|
"§cMaximum " + "length" + (cast ? " is " + (int) ((ConfigEntry) info).getMax() : " is " + ((ConfigEntry) info).getMax())));
|
||||||
|
}
|
||||||
|
|
||||||
|
((EntryInfo) info.guiValue).tempValue = stringValue;
|
||||||
|
editBox.setTextColor(((ConfigEntry) info).isValid(value) == 0 ? 0xFFFFFFFF : 0xFFFF7777);
|
||||||
|
// button.active = entries.stream().allMatch(e -> e.inLimits);
|
||||||
|
|
||||||
|
|
||||||
|
if (((ConfigEntry) info).isValid(value) == 0 && info.getType() != List.class) {
|
||||||
|
if (!cast)
|
||||||
|
((ConfigEntry) info).setWithoutSaving(value);
|
||||||
|
else
|
||||||
|
((ConfigEntry) info).setWithoutSaving(value.intValue());
|
||||||
|
}
|
||||||
|
// else if (((ConfigEntry) info).isValid() == 0)
|
||||||
|
// {
|
||||||
|
// if (((List<String>) info.get()).size() == ((EntryInfo) info.guiValue).index)
|
||||||
|
// info.set(((List<String>) info.get()).add(""));
|
||||||
|
// info.set(((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;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
//==============//
|
||||||
|
// GUI handling //
|
||||||
|
//==============//
|
||||||
|
|
||||||
|
/**
|
||||||
|
* if you want to get this config gui's screen call this
|
||||||
|
*/
|
||||||
|
public static Screen getScreen(ConfigBase configBase, Screen parent, String category) {
|
||||||
|
return new ConfigScreen(configBase, parent, category);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pain
|
||||||
|
*/
|
||||||
|
private static class ConfigScreen extends Screen {
|
||||||
|
protected ConfigScreen(ConfigBase configBase, Screen parent, String category) {
|
||||||
|
#if PRE_MC_1_19
|
||||||
|
super(new TranslatableComponent(
|
||||||
|
#else
|
||||||
|
super(Component.translatable(
|
||||||
|
#endif
|
||||||
|
I18n.exists(configBase.modID + ".config" + (category.isEmpty() ? "." + category : "") + ".title") ?
|
||||||
|
configBase.modID + ".config.title" :
|
||||||
|
configBase.modID + ".config" + (category.isEmpty() ? "" : "." + category) + ".title")
|
||||||
|
);
|
||||||
|
this.configBase = configBase;
|
||||||
|
this.parent = parent;
|
||||||
|
this.category = category;
|
||||||
|
this.translationPrefix = configBase.modID + ".config.";
|
||||||
|
}
|
||||||
|
private final ConfigBase configBase;
|
||||||
|
|
||||||
|
private final String translationPrefix;
|
||||||
|
private final Screen parent;
|
||||||
|
private final String category;
|
||||||
|
private ConfigListWidget list;
|
||||||
|
private boolean reload = false;
|
||||||
|
|
||||||
|
// Real Time config update //
|
||||||
|
@Override
|
||||||
|
public void tick() {
|
||||||
|
super.tick();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When you close it, it goes to the previous screen and saves
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void onClose() {
|
||||||
|
ConfigBase.INSTANCE.configFileINSTANCE.saveToFile();
|
||||||
|
Objects.requireNonNull(minecraft).setScreen(this.parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
// addRenderableWidget in 1.17 and over
|
||||||
|
// addButton in 1.16 and below
|
||||||
|
private Button addBtn(Button button) {
|
||||||
|
#if PRE_MC_1_17_1
|
||||||
|
this.addButton(button);
|
||||||
|
#else
|
||||||
|
this.addRenderableWidget(button);
|
||||||
|
#endif
|
||||||
|
return button;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void init() {
|
||||||
|
super.init();
|
||||||
|
if (!reload)
|
||||||
|
ConfigBase.INSTANCE.configFileINSTANCE.loadFromFile();
|
||||||
|
|
||||||
|
addBtn(new Button(this.width / 2 - 154, this.height - 28, 150, 20, CommonComponents.GUI_CANCEL, button -> {
|
||||||
|
ConfigBase.INSTANCE.configFileINSTANCE.loadFromFile();
|
||||||
|
Objects.requireNonNull(minecraft).setScreen(parent);
|
||||||
|
}));
|
||||||
|
Button done = addBtn(new Button(this.width / 2 + 4, this.height - 28, 150, 20, CommonComponents.GUI_DONE, (button) -> {
|
||||||
|
ConfigBase.INSTANCE.configFileINSTANCE.saveToFile();
|
||||||
|
Objects.requireNonNull(minecraft).setScreen(parent);
|
||||||
|
}));
|
||||||
|
|
||||||
|
this.list = new ConfigListWidget(this.minecraft, this.width * 2, this.height, 32, this.height - 32, 25);
|
||||||
|
if (this.minecraft != null && this.minecraft.level != null)
|
||||||
|
this.list.setRenderBackground(false);
|
||||||
|
this.addWidget(this.list);
|
||||||
|
for (AbstractConfigType info : ConfigBase.INSTANCE.entries) {
|
||||||
|
if (info.getCategory().matches(category) && info.getAppearance().showInGui) {
|
||||||
|
initEntry(info, this.translationPrefix);
|
||||||
|
#if PRE_MC_1_19
|
||||||
|
TranslatableComponent name = new TranslatableComponent(translationPrefix + info.getNameWCategory());
|
||||||
|
#else
|
||||||
|
Component name = Component.translatable(translationPrefix + info.getNameWCategory());
|
||||||
|
#endif
|
||||||
|
if (ConfigEntry.class.isAssignableFrom(info.getClass())) {
|
||||||
|
#if PRE_MC_1_19
|
||||||
|
Button resetButton = new Button(this.width - ConfigScreenConfigs.SpaceFromRightScreen - 150 - ConfigScreenConfigs.ButtonWidthSpacing - ConfigScreenConfigs.ResetButtonWidth, 0, ConfigScreenConfigs.ResetButtonWidth, 20, new TextComponent("Reset").withStyle(ChatFormatting.RED), (button -> {
|
||||||
|
#else
|
||||||
|
Button resetButton = new Button(this.width - ConfigScreenConfigs.SpaceFromRightScreen - 150 - ConfigScreenConfigs.ButtonWidthSpacing - ConfigScreenConfigs.ResetButtonWidth, 0, ConfigScreenConfigs.ResetButtonWidth, 20, Component.translatable("Reset").withStyle(ChatFormatting.RED), (button -> {
|
||||||
|
#endif
|
||||||
|
((ConfigEntry) info).setWithoutSaving(((ConfigEntry) info).getDefaultValue());
|
||||||
|
((EntryInfo) info.guiValue).index = 0;
|
||||||
|
this.reload = true;
|
||||||
|
Objects.requireNonNull(minecraft).setScreen(this);
|
||||||
|
}));
|
||||||
|
|
||||||
|
if (((EntryInfo) info.guiValue).widget instanceof Map.Entry) {
|
||||||
|
Map.Entry<Button.OnPress, Function<Object, Component>> widget = (Map.Entry<Button.OnPress, Function<Object, Component>>) ((EntryInfo) info.guiValue).widget;
|
||||||
|
if (info.getType().isEnum())
|
||||||
|
#if PRE_MC_1_19
|
||||||
|
widget.setValue(value -> new TranslatableComponent(translationPrefix + "enum." + info.getType().getSimpleName() + "." + info.get().toString()));
|
||||||
|
#else
|
||||||
|
widget.setValue(value -> Component.translatable(translationPrefix + "enum." + info.getType().getSimpleName() + "." + info.get().toString()));
|
||||||
|
#endif
|
||||||
|
this.list.addButton(new Button(this.width - 150 - ConfigScreenConfigs.SpaceFromRightScreen, 0, 150, 20, widget.getValue().apply(info.get()), widget.getKey()), resetButton, null, name);
|
||||||
|
} else if (((EntryInfo) info.guiValue).widget != null) {
|
||||||
|
EditBox widget = new EditBox(font, this.width - 150 - ConfigScreenConfigs.SpaceFromRightScreen + 2, 0, 150 - 4, 20, null);
|
||||||
|
widget.setMaxLength(150);
|
||||||
|
widget.insertText(String.valueOf(info.get()));
|
||||||
|
Predicate<String> processor = ((BiFunction<EditBox, Button, Predicate<String>>) ((EntryInfo) info.guiValue).widget).apply(widget, done);
|
||||||
|
widget.setFilter(processor);
|
||||||
|
this.list.addButton(widget, resetButton, null, name);
|
||||||
|
}
|
||||||
|
} else if (ConfigCategory.class.isAssignableFrom(info.getClass())) {
|
||||||
|
Button widget = new Button(this.width / 2 - 100, this.height - 28, 100 * 2, 20, name, (button -> {
|
||||||
|
ConfigBase.INSTANCE.configFileINSTANCE.saveToFile();
|
||||||
|
Objects.requireNonNull(minecraft).setScreen(ClassicConfigGUI.getScreen(this.configBase, this, ((ConfigCategory) info).getDestination()));
|
||||||
|
}));
|
||||||
|
this.list.addButton(widget, null, null, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void render(PoseStack matrices, int mouseX, int mouseY, float delta) {
|
||||||
|
this.renderBackground(matrices); // Renders background
|
||||||
|
this.list.render(matrices, mouseX, mouseY, delta); // Render buttons
|
||||||
|
drawCenteredString(matrices, font, title, width / 2, 15, 0xFFFFFF); // Render title
|
||||||
|
|
||||||
|
// Render the tooltip only if it can find a tooltip in the language file
|
||||||
|
for (AbstractConfigType info : ConfigBase.INSTANCE.entries) {
|
||||||
|
if (info.getCategory().matches(category) && info.getAppearance().showInGui) {
|
||||||
|
if (list.getHoveredButton(mouseX, mouseY).isPresent()) {
|
||||||
|
AbstractWidget buttonWidget = list.getHoveredButton(mouseX, mouseY).get();
|
||||||
|
Component text = ButtonEntry.buttonsWithText.get(buttonWidget);
|
||||||
|
#if PRE_MC_1_19
|
||||||
|
TranslatableComponent name = new TranslatableComponent(this.translationPrefix + (info.category.isEmpty() ? "" : info.category + ".") + info.getName());
|
||||||
|
#else
|
||||||
|
Component name = Component.translatable(this.translationPrefix + (info.category.isEmpty() ? "" : info.category + ".") + info.getName());
|
||||||
|
#endif
|
||||||
|
String key = translationPrefix + (info.category.isEmpty() ? "" : info.category + ".") + info.getName() + ".@tooltip";
|
||||||
|
|
||||||
|
if (((EntryInfo) info.guiValue).error != null && text.equals(name))
|
||||||
|
renderTooltip(matrices, (Component) ((EntryInfo) info.guiValue).error.getValue(), mouseX, mouseY);
|
||||||
|
else if (I18n.exists(key) && (text != null && text.equals(name))) {
|
||||||
|
List<Component> list = new ArrayList<>();
|
||||||
|
for (String str : I18n.get(key).split("\n"))
|
||||||
|
#if PRE_MC_1_19
|
||||||
|
list.add(new TextComponent(str));
|
||||||
|
#else
|
||||||
|
list.add(Component.translatable(str));
|
||||||
|
#endif
|
||||||
|
renderComponentTooltip(matrices, list, mouseX, mouseY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
super.render(matrices, mouseX, mouseY, delta);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private static void initEntry(AbstractConfigType info, String translationPrefix) {
|
||||||
|
info.guiValue = new EntryInfo();
|
||||||
|
Class<?> fieldClass = info.getType();
|
||||||
|
|
||||||
|
if (ConfigEntry.class.isAssignableFrom(info.getClass())) {
|
||||||
|
if (fieldClass == Integer.class) {
|
||||||
|
// For int
|
||||||
|
textField(info, Integer::parseInt, INTEGER_ONLY_REGEX, true);
|
||||||
|
} else if (fieldClass == Double.class) {
|
||||||
|
// For double
|
||||||
|
textField(info, Double::parseDouble, DECIMAL_ONLY_REGEX, false);
|
||||||
|
} else if (fieldClass == String.class || fieldClass == List.class) {
|
||||||
|
// For string or list
|
||||||
|
textField(info, String::length, null, true);
|
||||||
|
} else if (fieldClass == Boolean.class) {
|
||||||
|
// For boolean
|
||||||
|
#if PRE_MC_1_19
|
||||||
|
Function<Object, Component> func = value -> new TextComponent((Boolean) value ? "True" : "False").withStyle((Boolean) value ? ChatFormatting.GREEN : ChatFormatting.RED);
|
||||||
|
#else
|
||||||
|
Function<Object, Component> func = value -> Component.translatable((Boolean) value ? "True" : "False").withStyle((Boolean) value ? ChatFormatting.GREEN : ChatFormatting.RED);
|
||||||
|
#endif
|
||||||
|
((EntryInfo) info.guiValue).widget = new AbstractMap.SimpleEntry<Button.OnPress, Function<Object, Component>>(button -> {
|
||||||
|
((ConfigEntry) info).setWithoutSaving(!(Boolean) info.get());
|
||||||
|
button.setMessage(func.apply(info.get()));
|
||||||
|
}, func);
|
||||||
|
}
|
||||||
|
else if (fieldClass.isEnum())
|
||||||
|
{
|
||||||
|
// For enum
|
||||||
|
List<?> values = Arrays.asList(info.getType().getEnumConstants());
|
||||||
|
#if PRE_MC_1_19
|
||||||
|
Function<Object, Component> func = value -> new TranslatableComponent(translationPrefix + "enum." + fieldClass.getSimpleName() + "." + info.get().toString());
|
||||||
|
#else
|
||||||
|
Function<Object, Component> func = value -> Component.translatable(translationPrefix + "enum." + fieldClass.getSimpleName() + "." + info.get().toString());
|
||||||
|
#endif
|
||||||
|
((EntryInfo) info.guiValue).widget = new AbstractMap.SimpleEntry<Button.OnPress, Function<Object, Component>>(button -> {
|
||||||
|
int index = values.indexOf(info.get()) + 1;
|
||||||
|
info.set(values.get(index >= values.size() ? 0 : index));
|
||||||
|
button.setMessage(func.apply(info.get()));
|
||||||
|
}, func);
|
||||||
|
}
|
||||||
|
} else if (ConfigCategory.class.isAssignableFrom(info.getClass())) {
|
||||||
|
// if (!info.info.getName().equals(""))
|
||||||
|
// info.name = new TranslatableComponent(info.info.getName());
|
||||||
|
}
|
||||||
|
// return info;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public static class ConfigListWidget extends ContainerObjectSelectionList<ButtonEntry> {
|
||||||
|
Font textRenderer;
|
||||||
|
|
||||||
|
public ConfigListWidget(Minecraft minecraftClient, int i, int j, int k, int l, int m) {
|
||||||
|
super(minecraftClient, i, j, k, l, m);
|
||||||
|
this.centerListVertically = false;
|
||||||
|
textRenderer = minecraftClient.font;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addButton(AbstractWidget button, AbstractWidget resetButton, AbstractWidget indexButton, Component text) {
|
||||||
|
this.addEntry(ButtonEntry.create(button, text, resetButton, indexButton));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getRowWidth() {
|
||||||
|
return 10000;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Optional<AbstractWidget> getHoveredButton(double mouseX, double mouseY) {
|
||||||
|
for (ButtonEntry buttonEntry : this.children()) {
|
||||||
|
if (buttonEntry.button != null && buttonEntry.button.isMouseOver(mouseX, mouseY)) {
|
||||||
|
return Optional.of(buttonEntry.button);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static class ButtonEntry extends ContainerObjectSelectionList.Entry<ButtonEntry> {
|
||||||
|
private static final Font textRenderer = Minecraft.getInstance().font;
|
||||||
|
public final AbstractWidget button;
|
||||||
|
private final AbstractWidget resetButton;
|
||||||
|
private final AbstractWidget indexButton;
|
||||||
|
private final Component text;
|
||||||
|
private final List<AbstractWidget> children = new ArrayList<>();
|
||||||
|
public static final Map<AbstractWidget, Component> buttonsWithText = new HashMap<>();
|
||||||
|
|
||||||
|
private ButtonEntry(AbstractWidget button, Component text, AbstractWidget resetButton, AbstractWidget indexButton) {
|
||||||
|
buttonsWithText.put(button, text);
|
||||||
|
this.button = button;
|
||||||
|
this.resetButton = resetButton;
|
||||||
|
this.text = text;
|
||||||
|
this.indexButton = indexButton;
|
||||||
|
if (button != null)
|
||||||
|
children.add(button);
|
||||||
|
if (resetButton != null)
|
||||||
|
children.add(resetButton);
|
||||||
|
if (indexButton != null)
|
||||||
|
children.add(indexButton);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ButtonEntry create(AbstractWidget button, Component text, AbstractWidget resetButton, AbstractWidget indexButton) {
|
||||||
|
return new ButtonEntry(button, text, resetButton, indexButton);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void render(PoseStack matrices, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean hovered, float tickDelta) {
|
||||||
|
if (button != null) {
|
||||||
|
button.y = y;
|
||||||
|
button.render(matrices, mouseX, mouseY, tickDelta);
|
||||||
|
}
|
||||||
|
if (resetButton != null) {
|
||||||
|
resetButton.y = y;
|
||||||
|
resetButton.render(matrices, mouseX, mouseY, tickDelta);
|
||||||
|
}
|
||||||
|
if (indexButton != null) {
|
||||||
|
indexButton.y = y;
|
||||||
|
indexButton.render(matrices, mouseX, mouseY, tickDelta);
|
||||||
|
}
|
||||||
|
if (text != null && (!text.getString().contains("spacer") || button != null))
|
||||||
|
GuiComponent.drawString(matrices, textRenderer, text, 12, y + 5, 0xFFFFFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<? extends GuiEventListener> children() {
|
||||||
|
return children;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only for 1.17 and over
|
||||||
|
// Remove in 1.16 and below
|
||||||
|
#if POST_MC_1_17_1
|
||||||
|
@Override
|
||||||
|
public List<? extends NarratableEntry> narratables() {
|
||||||
|
return children;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,94 @@
|
|||||||
|
package com.seibel.lod.common.wrappers.gui;
|
||||||
|
|
||||||
|
import com.mojang.blaze3d.vertex.PoseStack;
|
||||||
|
import com.seibel.lod.core.ModInfo;
|
||||||
|
import com.seibel.lod.core.config.gui.AbstractScreen;
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.client.gui.components.ContainerObjectSelectionList;
|
||||||
|
import net.minecraft.client.gui.screens.Screen;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
public class ConfigScreenMC {
|
||||||
|
public static Screen getScreen(Screen parent, AbstractScreen screen) {
|
||||||
|
|
||||||
|
return new ConfigScreenRenderer(parent, screen);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class ConfigScreenRenderer extends Screen {
|
||||||
|
private final Screen parent;
|
||||||
|
private ConfigListWidget list;
|
||||||
|
private AbstractScreen screen;
|
||||||
|
|
||||||
|
|
||||||
|
#if PRE_MC_1_19
|
||||||
|
public static net.minecraft.network.chat.TranslatableComponent translate (String str, Object... args) {
|
||||||
|
return new net.minecraft.network.chat.TranslatableComponent(str, args);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
public static net.minecraft.network.chat.MutableComponent translate (String str, Object... args) {
|
||||||
|
return net.minecraft.network.chat.Component.translatable(str, args);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
protected ConfigScreenRenderer(Screen parent, AbstractScreen screen) {
|
||||||
|
super(translate(ModInfo.ID + ".config.title"));
|
||||||
|
this.parent = parent;
|
||||||
|
this.screen = screen;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void init() {
|
||||||
|
// super.init();
|
||||||
|
screen.width = this.width;
|
||||||
|
screen.height = this.height;
|
||||||
|
screen.init(); // Init our own config screen
|
||||||
|
|
||||||
|
this.list = new ConfigListWidget(this.minecraft, this.width, this.height, 0, this.height, 25); // Select the area to tint
|
||||||
|
if (this.minecraft != null && this.minecraft.level != null) // Check if in game
|
||||||
|
this.list.setRenderBackground(false); // Disable from rendering
|
||||||
|
this.addWidget(this.list); // Add the tint to the things to be rendered
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void render(PoseStack matrices, int mouseX, int mouseY, float delta) {
|
||||||
|
this.renderBackground(matrices); // Render background
|
||||||
|
this.list.render(matrices, mouseX, mouseY, delta); // Renders the items in the render list (currently only used to tint background darker)
|
||||||
|
|
||||||
|
screen.width = this.width; // Is there a way to only call this when the window changes the size
|
||||||
|
screen.height = this.height; // Is there a way to only call this when the window changes the size
|
||||||
|
screen.mouseX = mouseX;
|
||||||
|
screen.mouseY = mouseY;
|
||||||
|
screen.render(delta); // Render everything on the main screen
|
||||||
|
|
||||||
|
super.render(matrices, mouseX, mouseY, delta); // Render the vanilla stuff (currently only used for the background and tint)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void tick() {
|
||||||
|
screen.tick();
|
||||||
|
if (screen.close)
|
||||||
|
onClose();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClose() {
|
||||||
|
screen.onClose();
|
||||||
|
Objects.requireNonNull(minecraft).setScreen(this.parent); // Goto the parent screen
|
||||||
|
}
|
||||||
|
|
||||||
|
// For checking if it should close when you press the escape key
|
||||||
|
@Override
|
||||||
|
public boolean shouldCloseOnEsc() {
|
||||||
|
return screen.shouldCloseOnEsc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class ConfigListWidget extends ContainerObjectSelectionList {
|
||||||
|
public ConfigListWidget(Minecraft minecraftClient, int i, int j, int k, int l, int m) {
|
||||||
|
super(minecraftClient, i, j, k, l, m);
|
||||||
|
this.centerListVertically = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
package com.seibel.lod.common.wrappers.gui;
|
||||||
|
|
||||||
|
import com.seibel.lod.core.config.ConfigBase;
|
||||||
|
import com.seibel.lod.core.config.gui.ConfigScreen;
|
||||||
|
import net.minecraft.client.gui.screens.Screen;
|
||||||
|
|
||||||
|
public class GetConfigScreen {
|
||||||
|
public static type useScreen = type.Classic;
|
||||||
|
public static enum type {
|
||||||
|
Classic,
|
||||||
|
OpenGL;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Screen getScreen(Screen parent) {
|
||||||
|
if (useScreen == type.Classic) {
|
||||||
|
return ClassicConfigGUI.getScreen(ConfigBase.INSTANCE, parent, "client");
|
||||||
|
} else if (useScreen == type.OpenGL) {
|
||||||
|
return ConfigScreenMC.getScreen(parent, new ConfigScreen());
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
package com.seibel.lod.common.wrappers.gui;
|
||||||
|
|
||||||
|
import com.seibel.lod.core.wrapperInterfaces.config.ILangWrapper;
|
||||||
|
import net.minecraft.client.resources.language.I18n;
|
||||||
|
|
||||||
|
public class LangWrapper implements ILangWrapper {
|
||||||
|
public static final LangWrapper INSTANCE = new LangWrapper();
|
||||||
|
@Override
|
||||||
|
public boolean langExists(String str) {
|
||||||
|
return I18n.exists(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getLang(String str) {
|
||||||
|
return I18n.get(str);
|
||||||
|
}
|
||||||
|
}
|
||||||
+29
-1
@@ -1,4 +1,23 @@
|
|||||||
package com.seibel.lod.common.wrappers.config;
|
/*
|
||||||
|
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
|
||||||
|
* licensed under the GNU LGPL v3 License.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2020-2022 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.lod.common.wrappers.gui;
|
||||||
|
|
||||||
import com.mojang.blaze3d.systems.RenderSystem;
|
import com.mojang.blaze3d.systems.RenderSystem;
|
||||||
import com.mojang.blaze3d.vertex.PoseStack;
|
import com.mojang.blaze3d.vertex.PoseStack;
|
||||||
@@ -11,9 +30,12 @@ import net.minecraft.resources.ResourceLocation;
|
|||||||
* Creates a button with a texture on it
|
* Creates a button with a texture on it
|
||||||
*/
|
*/
|
||||||
public class TexturedButtonWidget extends ImageButton {
|
public class TexturedButtonWidget extends ImageButton {
|
||||||
|
#if POST_MC_1_17_1
|
||||||
public TexturedButtonWidget(int x, int y, int width, int height, int u, int v, ResourceLocation texture, OnPress pressAction) {
|
public TexturedButtonWidget(int x, int y, int width, int height, int u, int v, ResourceLocation texture, OnPress pressAction) {
|
||||||
super(x, y, width, height, u, v, texture, pressAction);
|
super(x, y, width, height, u, v, texture, pressAction);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
public TexturedButtonWidget(int x, int y, int width, int height, int u, int v, int hoveredVOffset, ResourceLocation texture, int textureWidth, int textureHeight, OnPress pressAction) {
|
public TexturedButtonWidget(int x, int y, int width, int height, int u, int v, int hoveredVOffset, ResourceLocation texture, int textureWidth, int textureHeight, OnPress pressAction) {
|
||||||
super(x, y, width, height, u, v, hoveredVOffset, texture, textureWidth, textureHeight, pressAction);
|
super(x, y, width, height, u, v, hoveredVOffset, texture, textureWidth, textureHeight, pressAction);
|
||||||
}
|
}
|
||||||
@@ -28,9 +50,15 @@ public class TexturedButtonWidget extends ImageButton {
|
|||||||
|
|
||||||
@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 PRE_MC_1_17_1
|
||||||
|
Minecraft.getInstance().getTextureManager().bind(WIDGETS_LOCATION);
|
||||||
|
RenderSystem.color4f(1.0F, 1.0F, 1.0F, this.alpha);
|
||||||
|
#else
|
||||||
RenderSystem.setShader(GameRenderer::getPositionTexShader);
|
RenderSystem.setShader(GameRenderer::getPositionTexShader);
|
||||||
RenderSystem.setShaderTexture(0, WIDGETS_LOCATION);
|
RenderSystem.setShaderTexture(0, WIDGETS_LOCATION);
|
||||||
RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, this.alpha);
|
RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, this.alpha);
|
||||||
|
#endif
|
||||||
|
|
||||||
int i = this.getYImage(this.isHovered);
|
int i = this.getYImage(this.isHovered);
|
||||||
RenderSystem.enableBlend();
|
RenderSystem.enableBlend();
|
||||||
RenderSystem.defaultBlendFunc();
|
RenderSystem.defaultBlendFunc();
|
||||||
@@ -0,0 +1,188 @@
|
|||||||
|
package com.seibel.lod.common.wrappers.gui.updater;
|
||||||
|
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
import com.mojang.blaze3d.platform.NativeImage;
|
||||||
|
import com.mojang.blaze3d.vertex.PoseStack;
|
||||||
|
import com.seibel.lod.common.wrappers.gui.ClassicConfigGUI;
|
||||||
|
import com.seibel.lod.core.ModInfo;
|
||||||
|
import com.seibel.lod.core.config.Config;
|
||||||
|
import com.seibel.lod.core.jar.JarUtils;
|
||||||
|
import com.seibel.lod.core.jar.installer.MarkdownFormatter;
|
||||||
|
import com.seibel.lod.core.jar.installer.ModrinthGetter;
|
||||||
|
import com.seibel.lod.core.jar.updater.SelfUpdater;
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.client.StringSplitter;
|
||||||
|
import net.minecraft.client.gui.Font;
|
||||||
|
import net.minecraft.client.gui.GuiComponent;
|
||||||
|
import net.minecraft.client.gui.components.AbstractWidget;
|
||||||
|
import net.minecraft.client.gui.components.Button;
|
||||||
|
import net.minecraft.client.gui.components.ContainerObjectSelectionList;
|
||||||
|
import net.minecraft.client.gui.components.ImageButton;
|
||||||
|
import net.minecraft.client.gui.components.events.GuiEventListener;
|
||||||
|
import net.minecraft.client.gui.narration.NarratableEntry;
|
||||||
|
import net.minecraft.client.gui.screens.Screen;
|
||||||
|
import net.minecraft.client.renderer.texture.DynamicTexture;
|
||||||
|
import net.minecraft.network.chat.Component;
|
||||||
|
import net.minecraft.network.chat.FormattedText;
|
||||||
|
import net.minecraft.network.chat.Style;
|
||||||
|
import net.minecraft.network.chat.TextComponent;
|
||||||
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
import net.minecraft.util.FormattedCharSequence;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The screen that pops up if the mod has an update.
|
||||||
|
*
|
||||||
|
* @author coolGi
|
||||||
|
*/
|
||||||
|
// TODO: After finishing the config, rewrite this in openGL as well
|
||||||
|
// TODO: Make this
|
||||||
|
public class ChangelogScreen extends Screen {
|
||||||
|
private Screen parent;
|
||||||
|
private String versionID;
|
||||||
|
private List<String> changelog;
|
||||||
|
private TextArea changelogArea;
|
||||||
|
|
||||||
|
|
||||||
|
public ChangelogScreen(Screen parent, String versionID) {
|
||||||
|
super(translate(ModInfo.ID + ".updater.title"));
|
||||||
|
this.parent = parent;
|
||||||
|
this.versionID = versionID;
|
||||||
|
|
||||||
|
this.changelog = new ArrayList<>();
|
||||||
|
// Get the release changelog and split it by the new lines
|
||||||
|
List<String> unwrappedChangelog =
|
||||||
|
List.of(new MarkdownFormatter.MinecraftFormat().convertTo( // This formats markdown to minecraft's "§" characters
|
||||||
|
ModrinthGetter.changeLogs.get(versionID)
|
||||||
|
).split("\\n"));
|
||||||
|
// Makes the words wrap around to not go off the screen
|
||||||
|
for (String str: unwrappedChangelog) {
|
||||||
|
this.changelog.addAll(
|
||||||
|
MarkdownFormatter.splitString(str, 75)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
// Debugging
|
||||||
|
// System.out.println(this.changelog);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void init() {
|
||||||
|
super.init();
|
||||||
|
|
||||||
|
|
||||||
|
this.addBtn( // Close
|
||||||
|
new Button(5, this.height - 25, 100, 20, translate(ModInfo.ID + ".general.back"), (btn) -> {
|
||||||
|
this.onClose();
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
this.changelogArea = new TextArea(this.minecraft, this.width*2, this.height, 32, this.height - 32, 10);
|
||||||
|
for (int i = 0; i < changelog.size(); i++) {
|
||||||
|
this.changelogArea.addButton(new TextComponent(changelog.get(i)));
|
||||||
|
// drawString(matrices, this.font, changelog.get(i), this.width / 2 - 175, this.height / 2 - 100 + i*10, 0xFFFFFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void render(PoseStack matrices, int mouseX, int mouseY, float delta) {
|
||||||
|
this.renderBackground(matrices); // Render background
|
||||||
|
|
||||||
|
// Set the scroll position to the mouse height relative to the screen
|
||||||
|
this.changelogArea.setScrollAmount(
|
||||||
|
((double) mouseY)/((double) this.height) * this.changelogArea.getMaxScroll()
|
||||||
|
);
|
||||||
|
|
||||||
|
this.changelogArea.render(matrices, mouseX, mouseY, delta); // Render the changelog
|
||||||
|
|
||||||
|
super.render(matrices, mouseX, mouseY, delta); // Render the buttons
|
||||||
|
|
||||||
|
drawCenteredString(matrices, font, title, width / 2, 15, 0xFFFFFF); // Render title
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClose() {
|
||||||
|
Objects.requireNonNull(minecraft).setScreen(this.parent); // Goto the parent screen
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// addRenderableWidget in 1.17 and over
|
||||||
|
// addButton in 1.16 and below
|
||||||
|
private void addBtn(Button button) {
|
||||||
|
#if PRE_MC_1_17_1
|
||||||
|
this.addButton(button);
|
||||||
|
#else
|
||||||
|
this.addRenderableWidget(button);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#if PRE_MC_1_19
|
||||||
|
public static net.minecraft.network.chat.TranslatableComponent translate (String str, Object... args) {
|
||||||
|
return new net.minecraft.network.chat.TranslatableComponent(str, args);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
public static net.minecraft.network.chat.MutableComponent translate (String str, Object... args) {
|
||||||
|
return net.minecraft.network.chat.Component.translatable(str, args);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public static class TextArea extends ContainerObjectSelectionList<ButtonEntry> {
|
||||||
|
Font textRenderer;
|
||||||
|
|
||||||
|
public TextArea(Minecraft minecraftClient, int i, int j, int k, int l, int m) {
|
||||||
|
super(minecraftClient, i, j, k, l, m);
|
||||||
|
this.centerListVertically = false;
|
||||||
|
textRenderer = minecraftClient.font;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addButton(Component text) {
|
||||||
|
this.addEntry(ButtonEntry.create(text));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getRowWidth() {
|
||||||
|
return 10000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class ButtonEntry extends ContainerObjectSelectionList.Entry<ButtonEntry> {
|
||||||
|
private static final Font textRenderer = Minecraft.getInstance().font;
|
||||||
|
private final Component text;
|
||||||
|
private final List<AbstractWidget> children = new ArrayList<>();
|
||||||
|
|
||||||
|
private ButtonEntry(Component text) {
|
||||||
|
this.text = text;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ButtonEntry create(Component text) {
|
||||||
|
return new ButtonEntry(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void render(PoseStack matrices, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean hovered, float tickDelta) {
|
||||||
|
GuiComponent.drawString(matrices, textRenderer, text, 12, y + 5, 0xFFFFFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<? extends GuiEventListener> children() {
|
||||||
|
return children;
|
||||||
|
}
|
||||||
|
#if POST_MC_1_17_1
|
||||||
|
@Override
|
||||||
|
public List<? extends NarratableEntry> narratables() {
|
||||||
|
return children;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,159 @@
|
|||||||
|
package com.seibel.lod.common.wrappers.gui.updater;
|
||||||
|
|
||||||
|
import com.mojang.blaze3d.platform.NativeImage;
|
||||||
|
import com.mojang.blaze3d.vertex.PoseStack;
|
||||||
|
import com.seibel.lod.common.wrappers.gui.TexturedButtonWidget;
|
||||||
|
import com.seibel.lod.core.ModInfo;
|
||||||
|
import com.seibel.lod.core.config.Config;
|
||||||
|
import com.seibel.lod.core.jar.JarUtils;
|
||||||
|
import com.seibel.lod.core.jar.installer.ModrinthGetter;
|
||||||
|
import com.seibel.lod.core.jar.updater.SelfUpdater;
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.client.gui.components.Button;
|
||||||
|
import net.minecraft.client.gui.components.ImageButton;
|
||||||
|
import net.minecraft.client.gui.screens.Screen;
|
||||||
|
import net.minecraft.client.renderer.texture.DynamicTexture;
|
||||||
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The screen that pops up if the mod has an update.
|
||||||
|
*
|
||||||
|
* @author coolGi
|
||||||
|
*/
|
||||||
|
// TODO: After finishing the config, rewrite this in openGL as well
|
||||||
|
// and also maybe add this suggestion https://discord.com/channels/881614130614767666/1035863487110467625/1035949054485594192
|
||||||
|
public class UpdateModScreen extends Screen {
|
||||||
|
private Screen parent;
|
||||||
|
private String newVersionID;
|
||||||
|
|
||||||
|
|
||||||
|
public UpdateModScreen(Screen parent, String newVersionID) {
|
||||||
|
super(translate(ModInfo.ID + ".updater.title"));
|
||||||
|
this.parent = parent;
|
||||||
|
this.newVersionID = newVersionID;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void init() {
|
||||||
|
super.init();
|
||||||
|
|
||||||
|
|
||||||
|
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
|
||||||
|
this.addBtn(new ImageButton(
|
||||||
|
// Where the button is on the screen
|
||||||
|
this.width / 2 - 65, this.height / 2 - 110,
|
||||||
|
// Width and height of the button
|
||||||
|
130, 65,
|
||||||
|
// Offset
|
||||||
|
0, 0,
|
||||||
|
// Some textuary stuff
|
||||||
|
0, logoLocation, 130, 65,
|
||||||
|
// Create the button and tell it where to go
|
||||||
|
// For now it goes to the client option by default
|
||||||
|
(buttonWidget) -> System.out.println("Nice, you found an easter egg :)"), // TODO: Add a proper easter egg to pressing the logo (maybe with confetti)
|
||||||
|
// Add a title to the button
|
||||||
|
translate(ModInfo.ID + ".updater.title")
|
||||||
|
));
|
||||||
|
} catch (Exception e) { e.printStackTrace(); }
|
||||||
|
|
||||||
|
|
||||||
|
this.addBtn(new TexturedButtonWidget(
|
||||||
|
// Where the button is on the screen
|
||||||
|
this.width / 2 - 97, this.height / 2 + 8,
|
||||||
|
// Width and height of the button
|
||||||
|
20, 20,
|
||||||
|
// Offset
|
||||||
|
0, 0,
|
||||||
|
// Some textuary stuff
|
||||||
|
0, new ResourceLocation(ModInfo.ID, "textures/gui/changelog.png"), 20, 20,
|
||||||
|
// Create the button and tell it where to go
|
||||||
|
// For now it goes to the client option by default
|
||||||
|
(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
|
||||||
|
translate(ModInfo.ID + ".updater.title")
|
||||||
|
));
|
||||||
|
|
||||||
|
|
||||||
|
this.addBtn( // Update
|
||||||
|
new Button(this.width / 2 - 75, this.height / 2 + 8, 150, 20, translate(ModInfo.ID + ".updater.update"), (btn) -> {
|
||||||
|
SelfUpdater.deleteOldOnClose = true;
|
||||||
|
SelfUpdater.updateMod();
|
||||||
|
this.onClose();
|
||||||
|
})
|
||||||
|
);
|
||||||
|
this.addBtn( // Silent update
|
||||||
|
new Button(this.width / 2 - 75, this.height / 2 + 30, 150, 20, translate(ModInfo.ID + ".updater.silent"), (btn) -> {
|
||||||
|
Config.Client.AutoUpdater.promptForUpdate.set(false);
|
||||||
|
SelfUpdater.updateMod();
|
||||||
|
this.onClose();
|
||||||
|
})
|
||||||
|
);
|
||||||
|
this.addBtn( // Later (not now)
|
||||||
|
new Button(this.width / 2 + 2, this.height / 2 + 70, 100, 20, translate(ModInfo.ID + ".updater.later"), (btn) -> {
|
||||||
|
this.onClose();
|
||||||
|
})
|
||||||
|
);
|
||||||
|
this.addBtn( // Never
|
||||||
|
new Button(this.width / 2 - 102, this.height / 2 + 70, 100, 20, translate(ModInfo.ID + ".updater.never"), (btn) -> {
|
||||||
|
Config.Client.AutoUpdater.enableAutoUpdater.set(false);
|
||||||
|
this.onClose();
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void render(PoseStack matrices, int mouseX, int mouseY, float delta) {
|
||||||
|
this.renderBackground(matrices); // Render background
|
||||||
|
|
||||||
|
|
||||||
|
// Render the text's
|
||||||
|
drawCenteredString(matrices, this.font, translate(ModInfo.ID + ".updater.text1"), this.width / 2, this.height / 2 - 35, 0xFFFFFF);
|
||||||
|
drawCenteredString(matrices, this.font, translate(ModInfo.ID + ".updater.text2", ModInfo.VERSION, ModrinthGetter.releaseNames.get(this.newVersionID)), 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
|
||||||
|
public void onClose() {
|
||||||
|
Objects.requireNonNull(minecraft).setScreen(this.parent); // Goto the parent screen
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// addRenderableWidget in 1.17 and over
|
||||||
|
// addButton in 1.16 and below
|
||||||
|
private void addBtn(Button button) {
|
||||||
|
#if PRE_MC_1_17_1
|
||||||
|
this.addButton(button);
|
||||||
|
#else
|
||||||
|
this.addRenderableWidget(button);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#if PRE_MC_1_19
|
||||||
|
public static net.minecraft.network.chat.TranslatableComponent translate (String str, Object... args) {
|
||||||
|
return new net.minecraft.network.chat.TranslatableComponent(str, args);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
public static net.minecraft.network.chat.MutableComponent translate (String str, Object... args) {
|
||||||
|
return net.minecraft.network.chat.Component.translatable(str, args);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
+56
-224
@@ -1,76 +1,67 @@
|
|||||||
/*
|
/*
|
||||||
* This file is part of the Distant Horizon mod (formerly the LOD Mod),
|
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
|
||||||
* licensed under the GNU GPL v3 License.
|
* licensed under the GNU LGPL v3 License.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2020 James Seibel
|
* Copyright (C) 2020-2022 James Seibel
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
* the Free Software Foundation, version 3.
|
* the Free Software Foundation, version 3.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU Lesser General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* 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/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.seibel.lod.common.wrappers.minecraft;
|
package com.seibel.lod.common.wrappers.minecraft;
|
||||||
|
|
||||||
import java.awt.Color;
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.lang.invoke.MethodHandles;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
import com.mojang.blaze3d.platform.NativeImage;
|
import com.mojang.blaze3d.platform.NativeImage;
|
||||||
import com.mojang.blaze3d.platform.Window;
|
import com.seibel.lod.common.wrappers.world.ClientLevelWrapper;
|
||||||
|
import com.seibel.lod.common.wrappers.world.ServerLevelWrapper;
|
||||||
import com.seibel.lod.core.ModInfo;
|
import com.seibel.lod.core.ModInfo;
|
||||||
import com.seibel.lod.core.api.ApiShared;
|
import com.seibel.lod.core.enums.ELodDirection;
|
||||||
import com.seibel.lod.core.enums.LodDirection;
|
import com.seibel.lod.core.logging.DhLoggerBuilder;
|
||||||
import com.seibel.lod.core.util.LodUtil;
|
|
||||||
import com.seibel.lod.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
|
import com.seibel.lod.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
|
||||||
|
import com.seibel.lod.core.wrapperInterfaces.minecraft.IMinecraftSharedWrapper;
|
||||||
import com.seibel.lod.core.wrapperInterfaces.minecraft.IProfilerWrapper;
|
import com.seibel.lod.core.wrapperInterfaces.minecraft.IProfilerWrapper;
|
||||||
import com.seibel.lod.core.wrapperInterfaces.misc.ILightMapWrapper;
|
import com.seibel.lod.core.wrapperInterfaces.world.ILevelWrapper;
|
||||||
import com.seibel.lod.core.wrapperInterfaces.world.IDimensionTypeWrapper;
|
|
||||||
import com.seibel.lod.core.wrapperInterfaces.world.IWorldWrapper;
|
|
||||||
import com.seibel.lod.common.wrappers.McObjectConverter;
|
import com.seibel.lod.common.wrappers.McObjectConverter;
|
||||||
import com.seibel.lod.common.wrappers.block.BlockPosWrapper;
|
import com.seibel.lod.core.pos.DhBlockPos;
|
||||||
import com.seibel.lod.common.wrappers.chunk.ChunkPosWrapper;
|
import com.seibel.lod.core.pos.DhChunkPos;
|
||||||
import com.seibel.lod.common.wrappers.misc.LightMapWrapper;
|
|
||||||
import com.seibel.lod.common.wrappers.world.DimensionTypeWrapper;
|
|
||||||
import com.seibel.lod.common.wrappers.world.WorldWrapper;
|
|
||||||
|
|
||||||
import net.minecraft.CrashReport;
|
import net.minecraft.CrashReport;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.Options;
|
|
||||||
import net.minecraft.client.multiplayer.ClientLevel;
|
|
||||||
import net.minecraft.client.multiplayer.ClientPacketListener;
|
|
||||||
import net.minecraft.client.multiplayer.ServerData;
|
|
||||||
import net.minecraft.client.player.LocalPlayer;
|
import net.minecraft.client.player.LocalPlayer;
|
||||||
import net.minecraft.client.renderer.GameRenderer;
|
|
||||||
import net.minecraft.client.renderer.LevelRenderer;
|
|
||||||
import net.minecraft.client.renderer.LightTexture;
|
|
||||||
import net.minecraft.client.resources.model.ModelManager;
|
import net.minecraft.client.resources.model.ModelManager;
|
||||||
import net.minecraft.client.server.IntegratedServer;
|
|
||||||
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
|
||||||
import net.minecraft.network.chat.TextComponent;
|
import net.minecraft.network.chat.TextComponent;
|
||||||
|
#endif
|
||||||
import net.minecraft.server.level.ServerLevel;
|
import net.minecraft.server.level.ServerLevel;
|
||||||
import net.minecraft.world.entity.Entity;
|
|
||||||
import net.minecraft.world.level.ChunkPos;
|
import net.minecraft.world.level.ChunkPos;
|
||||||
import net.minecraft.world.level.dimension.DimensionType;
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A singleton that wraps the Minecraft class
|
* A singleton that wraps the Minecraft object.
|
||||||
* to allow for easier movement between Minecraft versions.
|
|
||||||
*
|
*
|
||||||
* @author James Seibel
|
* @author James Seibel
|
||||||
* @version 3-5-2022
|
* @version 3-5-2022
|
||||||
*/
|
*/
|
||||||
public class MinecraftClientWrapper implements IMinecraftClientWrapper
|
//@Environment(EnvType.CLIENT)
|
||||||
|
public class MinecraftClientWrapper implements IMinecraftClientWrapper, IMinecraftSharedWrapper
|
||||||
{
|
{
|
||||||
|
private static final Logger LOGGER = DhLoggerBuilder.getLogger(MethodHandles.lookup().lookupClass().getSimpleName());
|
||||||
|
|
||||||
public static final MinecraftClientWrapper INSTANCE = new MinecraftClientWrapper();
|
public static final MinecraftClientWrapper INSTANCE = new MinecraftClientWrapper();
|
||||||
|
|
||||||
public final Minecraft mc = Minecraft.getInstance();
|
public final Minecraft mc = Minecraft.getInstance();
|
||||||
@@ -116,7 +107,7 @@ public class MinecraftClientWrapper implements IMinecraftClientWrapper
|
|||||||
//=================//
|
//=================//
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public float getShade(LodDirection lodDirection) {
|
public float getShade(ELodDirection lodDirection) {
|
||||||
if (mc.level != null)
|
if (mc.level != null)
|
||||||
{
|
{
|
||||||
Direction mcDir = McObjectConverter.Convert(lodDirection);
|
Direction mcDir = McObjectConverter.Convert(lodDirection);
|
||||||
@@ -149,72 +140,6 @@ public class MinecraftClientWrapper implements IMinecraftClientWrapper
|
|||||||
return mc.getCurrentServer().version.getString();
|
return mc.getCurrentServer().version.getString();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns the dimension the player is currently in */
|
|
||||||
@Override
|
|
||||||
public IDimensionTypeWrapper getCurrentDimension()
|
|
||||||
{
|
|
||||||
if (mc.player != null)
|
|
||||||
return DimensionTypeWrapper.getDimensionTypeWrapper(mc.player.level.dimensionType());
|
|
||||||
else return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getCurrentDimensionId()
|
|
||||||
{
|
|
||||||
return LodUtil.getDimensionIDFromWorld(WorldWrapper.getWorldWrapper(mc.level));
|
|
||||||
}
|
|
||||||
|
|
||||||
/** This texture changes every frame */
|
|
||||||
@Override
|
|
||||||
public ILightMapWrapper getCurrentLightMap()
|
|
||||||
{
|
|
||||||
// get the current lightMap if the cache is empty
|
|
||||||
if (lightMap == null)
|
|
||||||
{
|
|
||||||
LightTexture tex = mc.gameRenderer.lightTexture();
|
|
||||||
lightMap = tex.lightPixels;
|
|
||||||
}
|
|
||||||
return new LightMapWrapper(lightMap);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the color int at the given pixel coordinates
|
|
||||||
* from the current lightmap.
|
|
||||||
* @param blockLight x location in texture space
|
|
||||||
* @param skyLight z location in texture space
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public int getColorIntFromLightMap(int blockLight, int skyLight)
|
|
||||||
{
|
|
||||||
if (lightMap == null)
|
|
||||||
{
|
|
||||||
sendChatMessage("new");
|
|
||||||
// make sure the lightMap is up-to-date
|
|
||||||
getCurrentLightMap();
|
|
||||||
}
|
|
||||||
|
|
||||||
return lightMap.getPixelRGBA(blockLight, skyLight);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the Color at the given pixel coordinates
|
|
||||||
* from the current lightmap.
|
|
||||||
* @param blockLight x location in texture space
|
|
||||||
* @param skyLight z location in texture space
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public Color getColorFromLightMap(int blockLight, int skyLight) {
|
|
||||||
if (lightMap == null) {
|
|
||||||
// make sure the lightMap is up-to-date
|
|
||||||
getCurrentLightMap();
|
|
||||||
}
|
|
||||||
|
|
||||||
return LodUtil.intToColor(lightMap.getPixelRGBA(blockLight, skyLight));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//=============//
|
//=============//
|
||||||
// Simple gets //
|
// Simple gets //
|
||||||
//=============//
|
//=============//
|
||||||
@@ -231,22 +156,21 @@ public class MinecraftClientWrapper implements IMinecraftClientWrapper
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BlockPosWrapper getPlayerBlockPos()
|
public DhBlockPos getPlayerBlockPos()
|
||||||
{
|
{
|
||||||
BlockPos playerPos = getPlayer().blockPosition();
|
BlockPos playerPos = getPlayer().blockPosition();
|
||||||
return new BlockPosWrapper(playerPos.getX(), playerPos.getY(), playerPos.getZ());
|
return new DhBlockPos(playerPos.getX(), playerPos.getY(), playerPos.getZ());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ChunkPosWrapper getPlayerChunkPos()
|
public DhChunkPos getPlayerChunkPos()
|
||||||
{
|
{
|
||||||
|
#if PRE_MC_1_17_1
|
||||||
|
ChunkPos playerPos = new ChunkPos(getPlayer().blockPosition());
|
||||||
|
#else
|
||||||
ChunkPos playerPos = getPlayer().chunkPosition();
|
ChunkPos playerPos = getPlayer().chunkPosition();
|
||||||
return new ChunkPosWrapper(playerPos.x, playerPos.z);
|
#endif
|
||||||
}
|
return new DhChunkPos(playerPos.x, playerPos.z);
|
||||||
|
|
||||||
public Options getOptions()
|
|
||||||
{
|
|
||||||
return mc.options;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ModelManager getModelManager()
|
public ModelManager getModelManager()
|
||||||
@@ -254,71 +178,11 @@ public class MinecraftClientWrapper implements IMinecraftClientWrapper
|
|||||||
return mc.getModelManager();
|
return mc.getModelManager();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ClientLevel getClientLevel()
|
|
||||||
{
|
|
||||||
return mc.level;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public IWorldWrapper getWrappedServerWorld()
|
|
||||||
{
|
|
||||||
if (mc.level == null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
DimensionType dimension = mc.level.dimensionType();
|
|
||||||
IntegratedServer server = mc.getSingleplayerServer();
|
|
||||||
|
|
||||||
if (server == null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
ServerLevel serverWorld = null;
|
|
||||||
Iterable<ServerLevel> worlds = server.getAllLevels();
|
|
||||||
for (ServerLevel world : worlds)
|
|
||||||
{
|
|
||||||
if (world.dimensionType() == dimension)
|
|
||||||
{
|
|
||||||
serverWorld = world;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return WorldWrapper.getWorldWrapper(serverWorld);
|
|
||||||
}
|
|
||||||
|
|
||||||
public WorldWrapper getWrappedClientLevel()
|
|
||||||
{
|
|
||||||
return WorldWrapper.getWorldWrapper(mc.level);
|
|
||||||
}
|
|
||||||
|
|
||||||
public WorldWrapper getWrappedServerLevel()
|
|
||||||
{
|
|
||||||
|
|
||||||
if (mc.level == null)
|
|
||||||
return null;
|
|
||||||
DimensionType dimension = mc.level.dimensionType();
|
|
||||||
IntegratedServer server = mc.getSingleplayerServer();
|
|
||||||
if (server == null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
Iterable<ServerLevel> worlds = server.getAllLevels();
|
|
||||||
ServerLevel returnWorld = null;
|
|
||||||
|
|
||||||
for (ServerLevel world : worlds)
|
|
||||||
{
|
|
||||||
if (world.dimensionType() == dimension)
|
|
||||||
{
|
|
||||||
returnWorld = world;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return WorldWrapper.getWorldWrapper(returnWorld);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public IWorldWrapper getWrappedClientWorld()
|
public ILevelWrapper getWrappedClientWorld()
|
||||||
{
|
{
|
||||||
return WorldWrapper.getWorldWrapper(mc.level);
|
return ClientLevelWrapper.getWrapper(mc.level);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -334,66 +198,19 @@ public class MinecraftClientWrapper implements IMinecraftClientWrapper
|
|||||||
profilerWrapper = new ProfilerWrapper(mc.getProfiler());
|
profilerWrapper = new ProfilerWrapper(mc.getProfiler());
|
||||||
else if (mc.getProfiler() != profilerWrapper.profiler)
|
else if (mc.getProfiler() != profilerWrapper.profiler)
|
||||||
profilerWrapper.profiler = mc.getProfiler();
|
profilerWrapper.profiler = mc.getProfiler();
|
||||||
|
return profilerWrapper;
|
||||||
return profilerWrapper; }
|
|
||||||
|
|
||||||
public ClientPacketListener getConnection()
|
|
||||||
{
|
|
||||||
return mc.getConnection();
|
|
||||||
}
|
|
||||||
|
|
||||||
public GameRenderer getGameRenderer()
|
|
||||||
{
|
|
||||||
return mc.gameRenderer;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Entity getCameraEntity()
|
|
||||||
{
|
|
||||||
return mc.cameraEntity;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Window getWindow()
|
|
||||||
{
|
|
||||||
return mc.getWindow();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public float getSkyDarken(float partialTicks)
|
|
||||||
{
|
|
||||||
return mc.level.getSkyDarken(partialTicks);
|
|
||||||
}
|
|
||||||
|
|
||||||
public IntegratedServer getSinglePlayerServer()
|
|
||||||
{
|
|
||||||
return mc.getSingleplayerServer();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean connectedToServer()
|
|
||||||
{
|
|
||||||
return mc.getCurrentServer() != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ServerData getCurrentServer()
|
|
||||||
{
|
|
||||||
return mc.getCurrentServer();
|
|
||||||
}
|
|
||||||
|
|
||||||
public LevelRenderer getLevelRenderer()
|
|
||||||
{
|
|
||||||
return mc.levelRenderer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns all worlds available to the server */
|
/** Returns all worlds available to the server */
|
||||||
@Override
|
@Override
|
||||||
public ArrayList<IWorldWrapper> getAllServerWorlds()
|
public ArrayList<ILevelWrapper> getAllServerWorlds()
|
||||||
{
|
{
|
||||||
ArrayList<IWorldWrapper> worlds = new ArrayList<IWorldWrapper>();
|
ArrayList<ILevelWrapper> worlds = new ArrayList<ILevelWrapper>();
|
||||||
|
|
||||||
Iterable<ServerLevel> serverWorlds = mc.getSingleplayerServer().getAllLevels();
|
Iterable<ServerLevel> serverWorlds = mc.getSingleplayerServer().getAllLevels();
|
||||||
for (ServerLevel world : serverWorlds)
|
for (ServerLevel world : serverWorlds)
|
||||||
{
|
{
|
||||||
worlds.add(WorldWrapper.getWorldWrapper(world));
|
worlds.add(ServerLevelWrapper.getWrapper(world));
|
||||||
}
|
}
|
||||||
|
|
||||||
return worlds;
|
return worlds;
|
||||||
@@ -404,7 +221,11 @@ public class MinecraftClientWrapper implements IMinecraftClientWrapper
|
|||||||
@Override
|
@Override
|
||||||
public void sendChatMessage(String string)
|
public void sendChatMessage(String string)
|
||||||
{
|
{
|
||||||
|
#if PRE_MC_1_19
|
||||||
getPlayer().sendMessage(new TextComponent(string), getPlayer().getUUID());
|
getPlayer().sendMessage(new TextComponent(string), getPlayer().getUUID());
|
||||||
|
#else
|
||||||
|
getPlayer().sendSystemMessage(net.minecraft.network.chat.Component.translatable(string));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -418,13 +239,24 @@ public class MinecraftClientWrapper implements IMinecraftClientWrapper
|
|||||||
@Override
|
@Override
|
||||||
public void crashMinecraft(String errorMessage, Throwable exception)
|
public void crashMinecraft(String errorMessage, Throwable exception)
|
||||||
{
|
{
|
||||||
ApiShared.LOGGER.error(ModInfo.READABLE_NAME + " had the following error: [" + errorMessage + "]. Crashing Minecraft...");
|
LOGGER.error(ModInfo.READABLE_NAME + " had the following error: [" + errorMessage + "]. Crashing Minecraft...");
|
||||||
CrashReport report = new CrashReport(errorMessage, exception);
|
CrashReport report = new CrashReport(errorMessage, exception);
|
||||||
Minecraft.crash(report);
|
Minecraft.crash(report);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getOptionsObject()
|
||||||
|
{
|
||||||
|
return mc.options;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isDedicatedServer() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public File getInstallationDirectory() {
|
||||||
|
return mc.gameDirectory;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+23
@@ -0,0 +1,23 @@
|
|||||||
|
package com.seibel.lod.common.wrappers.minecraft;
|
||||||
|
|
||||||
|
import com.seibel.lod.core.wrapperInterfaces.minecraft.IMinecraftSharedWrapper;
|
||||||
|
import net.minecraft.server.dedicated.DedicatedServer;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
//@Environment(EnvType.SERVER)
|
||||||
|
public class MinecraftDedicatedServerWrapper implements IMinecraftSharedWrapper {
|
||||||
|
public static final MinecraftDedicatedServerWrapper INSTANCE = new MinecraftDedicatedServerWrapper();
|
||||||
|
private MinecraftDedicatedServerWrapper() {}
|
||||||
|
public DedicatedServer dedicatedServer = null;
|
||||||
|
@Override
|
||||||
|
public boolean isDedicatedServer() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public File getInstallationDirectory() {
|
||||||
|
if (dedicatedServer == null)
|
||||||
|
throw new IllegalStateException("Trying to get Installation Direction before Dedicated server complete initialization!");
|
||||||
|
return dedicatedServer.getServerDirectory();
|
||||||
|
}
|
||||||
|
}
|
||||||
+136
-145
@@ -1,48 +1,73 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
|
||||||
|
* licensed under the GNU LGPL v3 License.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2020-2022 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.lod.common.wrappers.minecraft;
|
package com.seibel.lod.common.wrappers.minecraft;
|
||||||
|
|
||||||
import java.awt.*;
|
import java.awt.Color;
|
||||||
|
import java.lang.invoke.MethodHandles;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.LinkedHashSet;
|
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import com.mojang.blaze3d.pipeline.RenderTarget;
|
import com.mojang.blaze3d.pipeline.RenderTarget;
|
||||||
import com.mojang.blaze3d.platform.NativeImage;
|
import com.mojang.blaze3d.platform.NativeImage;
|
||||||
import com.mojang.blaze3d.systems.RenderSystem;
|
import com.mojang.blaze3d.systems.RenderSystem;
|
||||||
|
import com.seibel.lod.core.dependencyInjection.SingletonInjector;
|
||||||
|
import com.seibel.lod.core.pos.DhChunkPos;
|
||||||
import com.seibel.lod.common.wrappers.misc.LightMapWrapper;
|
import com.seibel.lod.common.wrappers.misc.LightMapWrapper;
|
||||||
import com.seibel.lod.core.api.ApiShared;
|
import com.seibel.lod.core.dependencyInjection.ModAccessorInjector;
|
||||||
import com.seibel.lod.core.api.ClientApi;
|
|
||||||
import com.seibel.lod.core.handlers.dependencyInjection.ModAccessorHandler;
|
|
||||||
import com.seibel.lod.core.handlers.dependencyInjection.SingletonHandler;
|
|
||||||
import com.seibel.lod.core.util.LodUtil;
|
|
||||||
|
|
||||||
import net.minecraft.client.renderer.LightTexture;
|
import com.seibel.lod.core.logging.DhLoggerBuilder;
|
||||||
|
import com.seibel.lod.core.wrapperInterfaces.misc.ILightMapWrapper;
|
||||||
|
|
||||||
import com.mojang.math.Vector3f;
|
import com.mojang.math.Vector3f;
|
||||||
import com.seibel.lod.core.objects.math.Mat4f;
|
import com.seibel.lod.core.util.math.Mat4f;
|
||||||
import com.seibel.lod.core.objects.math.Vec3d;
|
import com.seibel.lod.core.util.math.Vec3d;
|
||||||
import com.seibel.lod.core.objects.math.Vec3f;
|
import com.seibel.lod.core.util.math.Vec3f;
|
||||||
import com.seibel.lod.core.wrapperInterfaces.IWrapperFactory;
|
import com.seibel.lod.core.wrapperInterfaces.IWrapperFactory;
|
||||||
import com.seibel.lod.core.wrapperInterfaces.block.AbstractBlockPosWrapper;
|
|
||||||
import com.seibel.lod.core.wrapperInterfaces.chunk.AbstractChunkPosWrapper;
|
|
||||||
import com.seibel.lod.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
|
import com.seibel.lod.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
|
||||||
|
import com.seibel.lod.core.wrapperInterfaces.modAccessor.IBCLibAccessor;
|
||||||
|
import com.seibel.lod.core.wrapperInterfaces.modAccessor.IModChecker;
|
||||||
import com.seibel.lod.core.wrapperInterfaces.modAccessor.IOptifineAccessor;
|
import com.seibel.lod.core.wrapperInterfaces.modAccessor.IOptifineAccessor;
|
||||||
import com.seibel.lod.core.wrapperInterfaces.modAccessor.ISodiumAccessor;
|
import com.seibel.lod.core.wrapperInterfaces.modAccessor.ISodiumAccessor;
|
||||||
import com.seibel.lod.common.wrappers.McObjectConverter;
|
import com.seibel.lod.common.wrappers.McObjectConverter;
|
||||||
import com.seibel.lod.common.wrappers.WrapperFactory;
|
import com.seibel.lod.common.wrappers.WrapperFactory;
|
||||||
import com.seibel.lod.common.wrappers.block.BlockPosWrapper;
|
import com.seibel.lod.core.pos.DhBlockPos;
|
||||||
|
|
||||||
import net.minecraft.client.Camera;
|
import net.minecraft.client.Camera;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.renderer.FogRenderer;
|
import net.minecraft.client.renderer.FogRenderer;
|
||||||
import net.minecraft.client.renderer.GameRenderer;
|
|
||||||
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;
|
||||||
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
|
||||||
|
import net.minecraft.tags.FluidTags;
|
||||||
|
import net.minecraft.world.level.material.FluidState;
|
||||||
|
import org.lwjgl.opengl.GL15;
|
||||||
|
#else
|
||||||
import net.minecraft.world.level.material.FogType;
|
import net.minecraft.world.level.material.FogType;
|
||||||
|
#endif
|
||||||
import net.minecraft.world.phys.AABB;
|
import net.minecraft.world.phys.AABB;
|
||||||
import net.minecraft.world.phys.Vec3;
|
import net.minecraft.world.phys.Vec3;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -52,28 +77,35 @@ import net.minecraft.world.phys.Vec3;
|
|||||||
* @author James Seibel
|
* @author James Seibel
|
||||||
* @version 12-12-2021
|
* @version 12-12-2021
|
||||||
*/
|
*/
|
||||||
|
//@Environment(EnvType.CLIENT)
|
||||||
public class MinecraftRenderWrapper implements IMinecraftRenderWrapper
|
public class MinecraftRenderWrapper implements IMinecraftRenderWrapper
|
||||||
{
|
{
|
||||||
public static final MinecraftRenderWrapper INSTANCE = new MinecraftRenderWrapper();
|
public static final MinecraftRenderWrapper INSTANCE = new MinecraftRenderWrapper();
|
||||||
|
|
||||||
|
private static final Logger LOGGER = DhLoggerBuilder.getLogger(MethodHandles.lookup().lookupClass().getSimpleName());
|
||||||
private static final Minecraft MC = Minecraft.getInstance();
|
private static final Minecraft MC = Minecraft.getInstance();
|
||||||
private static final GameRenderer GAME_RENDERER = MC.gameRenderer;
|
|
||||||
private static final IWrapperFactory FACTORY = WrapperFactory.INSTANCE;
|
private static final IWrapperFactory FACTORY = WrapperFactory.INSTANCE;
|
||||||
|
|
||||||
|
private static final IOptifineAccessor OPTIFINE_ACCESSOR = ModAccessorInjector.INSTANCE.get(IOptifineAccessor.class);
|
||||||
|
|
||||||
|
public LightMapWrapper lightmap = null;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Vec3f getLookAtVector()
|
public Vec3f getLookAtVector()
|
||||||
{
|
{
|
||||||
Camera camera = GAME_RENDERER.getMainCamera();
|
Camera camera = MC.gameRenderer.getMainCamera();
|
||||||
Vector3f cameraDir = camera.getLookVector();
|
Vector3f cameraDir = camera.getLookVector();
|
||||||
return new Vec3f(cameraDir.x(), cameraDir.y(), cameraDir.z());
|
return new Vec3f(cameraDir.x(), cameraDir.y(), cameraDir.z());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AbstractBlockPosWrapper getCameraBlockPosition()
|
public DhBlockPos getCameraBlockPosition()
|
||||||
{
|
{
|
||||||
Camera camera = GAME_RENDERER.getMainCamera();
|
Camera camera = MC.gameRenderer.getMainCamera();
|
||||||
BlockPos blockPos = camera.getBlockPosition();
|
BlockPos blockPos = camera.getBlockPosition();
|
||||||
return new BlockPosWrapper(blockPos.getX(), blockPos.getY(), blockPos.getZ());
|
return new DhBlockPos(blockPos.getX(), blockPos.getY(), blockPos.getZ());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -85,7 +117,7 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper
|
|||||||
@Override
|
@Override
|
||||||
public Vec3d getCameraExactPosition()
|
public Vec3d getCameraExactPosition()
|
||||||
{
|
{
|
||||||
Camera camera = GAME_RENDERER.getMainCamera();
|
Camera camera = MC.gameRenderer.getMainCamera();
|
||||||
Vec3 projectedView = camera.getPosition();
|
Vec3 projectedView = camera.getPosition();
|
||||||
|
|
||||||
return new Vec3d(projectedView.x, projectedView.y, projectedView.z);
|
return new Vec3d(projectedView.x, projectedView.y, projectedView.z);
|
||||||
@@ -94,19 +126,35 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper
|
|||||||
@Override
|
@Override
|
||||||
public Mat4f getDefaultProjectionMatrix(float partialTicks)
|
public Mat4f getDefaultProjectionMatrix(float partialTicks)
|
||||||
{
|
{
|
||||||
return McObjectConverter.Convert(GAME_RENDERER.getProjectionMatrix(GAME_RENDERER.getFov(GAME_RENDERER.getMainCamera(), partialTicks, true)));
|
#if PRE_MC_1_17_1
|
||||||
|
return McObjectConverter.Convert(Minecraft.getInstance().gameRenderer.getProjectionMatrix(Minecraft.getInstance().gameRenderer.getMainCamera(), partialTicks, true));
|
||||||
|
#else
|
||||||
|
return McObjectConverter.Convert(MC.gameRenderer.getProjectionMatrix(MC.gameRenderer.getFov(MC.gameRenderer.getMainCamera(), partialTicks, true)));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double getGamma()
|
public double getGamma()
|
||||||
{
|
{
|
||||||
|
#if PRE_MC_1_19
|
||||||
return MC.options.gamma;
|
return MC.options.gamma;
|
||||||
|
#else
|
||||||
|
return MC.options.gamma().get();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Color getFogColor(float partialTicks) {
|
public Color getFogColor(float partialTicks) {
|
||||||
FogRenderer.setupColor(GAME_RENDERER.getMainCamera(), partialTicks, MC.level, 1, GAME_RENDERER.getDarkenWorldAmount(partialTicks));
|
if (SingletonInjector.INSTANCE.get(IModChecker.class).isModLoaded("bclib"))
|
||||||
|
return ModAccessorInjector.INSTANCE.get(IBCLibAccessor.class).getFogColor(); // BCLib uses a different fog method so we need to use that instead if they are loaded
|
||||||
|
|
||||||
|
#if PRE_MC_1_17_1
|
||||||
|
float[] colorValues = new float[4];
|
||||||
|
GL15.glGetFloatv(GL15.GL_FOG_COLOR, colorValues);
|
||||||
|
#else
|
||||||
|
FogRenderer.setupColor(MC.gameRenderer.getMainCamera(), partialTicks, MC.level, 1, MC.gameRenderer.getDarkenWorldAmount(partialTicks));
|
||||||
float[] colorValues = RenderSystem.getShaderFogColor();
|
float[] colorValues = RenderSystem.getShaderFogColor();
|
||||||
|
#endif
|
||||||
return new Color(colorValues[0], colorValues[1], colorValues[2], colorValues[3]);
|
return new Color(colorValues[0], colorValues[1], colorValues[2], colorValues[3]);
|
||||||
}
|
}
|
||||||
// getSpecialFogColor() is the same as getFogColor()
|
// getSpecialFogColor() is the same as getFogColor()
|
||||||
@@ -114,7 +162,11 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper
|
|||||||
@Override
|
@Override
|
||||||
public Color getSkyColor() {
|
public Color getSkyColor() {
|
||||||
if (MC.level.dimensionType().hasSkyLight()) {
|
if (MC.level.dimensionType().hasSkyLight()) {
|
||||||
|
#if PRE_MC_1_17_1
|
||||||
|
Vec3 colorValues = MC.level.getSkyColor(MC.gameRenderer.getMainCamera().getBlockPosition(), MC.getFrameTime());
|
||||||
|
#else
|
||||||
Vec3 colorValues = MC.level.getSkyColor(MC.gameRenderer.getMainCamera().getPosition(), MC.getFrameTime());
|
Vec3 colorValues = MC.level.getSkyColor(MC.gameRenderer.getMainCamera().getPosition(), MC.getFrameTime());
|
||||||
|
#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);
|
||||||
@@ -123,25 +175,42 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper
|
|||||||
@Override
|
@Override
|
||||||
public double getFov(float partialTicks)
|
public double getFov(float partialTicks)
|
||||||
{
|
{
|
||||||
return GAME_RENDERER.getFov(GAME_RENDERER.getMainCamera(), partialTicks, true);
|
return MC.gameRenderer.getFov(MC.gameRenderer.getMainCamera(), partialTicks, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Measured in chunks */
|
/** Measured in chunks */
|
||||||
@Override
|
@Override
|
||||||
public int getRenderDistance()
|
public int getRenderDistance()
|
||||||
{
|
{
|
||||||
return MC.options.getEffectiveRenderDistance();
|
#if PRE_MC_1_18_1
|
||||||
|
//FIXME: How to resolve this?
|
||||||
|
return MC.options.renderDistance;
|
||||||
|
#else
|
||||||
|
return MC.options.getEffectiveRenderDistance();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getScreenWidth()
|
public int getScreenWidth()
|
||||||
{
|
{
|
||||||
return MC.getWindow().getWidth();
|
int width = MC.getWindow().getWidth();
|
||||||
|
if (OPTIFINE_ACCESSOR != null)
|
||||||
|
{
|
||||||
|
// TODO remove comment after testing:
|
||||||
|
// this should fix the issue where different optifine render resolutions screw up the LOD rendering
|
||||||
|
width *= OPTIFINE_ACCESSOR.getRenderResolutionMultiplier();
|
||||||
|
}
|
||||||
|
return width;
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public int getScreenHeight()
|
public int getScreenHeight()
|
||||||
{
|
{
|
||||||
return MC.getWindow().getHeight();
|
int height = MC.getWindow().getHeight();
|
||||||
|
if (OPTIFINE_ACCESSOR != null)
|
||||||
|
{
|
||||||
|
height *= OPTIFINE_ACCESSOR.getRenderResolutionMultiplier();
|
||||||
|
}
|
||||||
|
return height;
|
||||||
}
|
}
|
||||||
|
|
||||||
private RenderTarget getRenderTarget() {
|
private RenderTarget getRenderTarget() {
|
||||||
@@ -170,19 +239,16 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper
|
|||||||
* <p>
|
* <p>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public boolean usingBackupGetVanillaRenderedChunks = true;
|
public boolean usingBackupGetVanillaRenderedChunks = false;
|
||||||
@Override
|
@Override
|
||||||
public HashSet<AbstractChunkPosWrapper> getVanillaRenderedChunks()
|
public HashSet<DhChunkPos> getVanillaRenderedChunks() {
|
||||||
{
|
ISodiumAccessor sodium = ModAccessorInjector.INSTANCE.get(ISodiumAccessor.class);
|
||||||
ISodiumAccessor sodium = ModAccessorHandler.get(ISodiumAccessor.class);
|
if (sodium != null) {
|
||||||
if (sodium != null)
|
|
||||||
{
|
|
||||||
return sodium.getNormalRenderedChunks();
|
return sodium.getNormalRenderedChunks();
|
||||||
}
|
}
|
||||||
IOptifineAccessor optifine = ModAccessorHandler.get(IOptifineAccessor.class);
|
IOptifineAccessor optifine = ModAccessorInjector.INSTANCE.get(IOptifineAccessor.class);
|
||||||
if (optifine != null)
|
if (optifine != null) {
|
||||||
{
|
HashSet<DhChunkPos> pos = optifine.getNormalRenderedChunks();
|
||||||
HashSet<AbstractChunkPosWrapper> pos = optifine.getNormalRenderedChunks();
|
|
||||||
if (pos == null)
|
if (pos == null)
|
||||||
pos = getMaximumRenderedChunks();
|
pos = getMaximumRenderedChunks();
|
||||||
return pos;
|
return pos;
|
||||||
@@ -190,14 +256,15 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper
|
|||||||
if (!usingBackupGetVanillaRenderedChunks) {
|
if (!usingBackupGetVanillaRenderedChunks) {
|
||||||
try {
|
try {
|
||||||
LevelRenderer levelRenderer = MC.levelRenderer;
|
LevelRenderer levelRenderer = MC.levelRenderer;
|
||||||
LinkedHashSet<LevelRenderer.RenderChunkInfo> chunks = levelRenderer.renderChunkStorage.get().renderChunks;
|
Collection<LevelRenderer.RenderChunkInfo> chunks =
|
||||||
|
#if PRE_MC_1_18_1 levelRenderer.renderChunks;
|
||||||
|
#else levelRenderer.renderChunkStorage.get().renderChunks; #endif
|
||||||
|
|
||||||
return (chunks.stream().map((chunk) -> {
|
return (chunks.stream().map((chunk) -> {
|
||||||
#if MC_VERSION_1_18_2
|
AABB chunkBoundingBox =
|
||||||
AABB chunkBoundingBox = chunk.chunk.getBoundingBox();
|
#if PRE_MC_1_18_2 chunk.chunk.bb;
|
||||||
#elif MC_VERSION_1_18_1
|
#else chunk.chunk.getBoundingBox(); #endif
|
||||||
AABB chunkBoundingBox = chunk.chunk.bb;
|
return new DhChunkPos(Math.floorDiv((int) chunkBoundingBox.minX, 16),
|
||||||
#endif
|
|
||||||
return FACTORY.createChunkPos(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)));
|
||||||
} catch (LinkageError e) {
|
} catch (LinkageError e) {
|
||||||
@@ -207,122 +274,46 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper
|
|||||||
+ " Using Backup Method.");
|
+ " Using Backup Method.");
|
||||||
MinecraftClientWrapper.INSTANCE.sendChatMessage(
|
MinecraftClientWrapper.INSTANCE.sendChatMessage(
|
||||||
"\u00A7eOverdraw prevention will be worse than normal.");
|
"\u00A7eOverdraw prevention will be worse than normal.");
|
||||||
} catch (Exception e2) {}
|
} catch (Exception e2) {
|
||||||
ApiShared.LOGGER.error("getVanillaRenderedChunks Error: ", e);
|
}
|
||||||
|
LOGGER.error("getVanillaRenderedChunks Error: ", e);
|
||||||
usingBackupGetVanillaRenderedChunks = true;
|
usingBackupGetVanillaRenderedChunks = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return getMaximumRenderedChunks();
|
return getMaximumRenderedChunks();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int[] getLightmapPixels()
|
public ILightMapWrapper getLightmapWrapper() {
|
||||||
{
|
return lightmap;
|
||||||
LightTexture tex = GAME_RENDERER.lightTexture();
|
|
||||||
tex.tick(); // This call makes no sense, but it fixes pause menu flicker bug
|
|
||||||
NativeImage lightMapPixels = tex.lightPixels;
|
|
||||||
LightMapWrapper lightMap = new LightMapWrapper(lightMapPixels);
|
|
||||||
|
|
||||||
|
|
||||||
int lightMapHeight = getLightmapTextureHeight();
|
|
||||||
int lightMapWidth = getLightmapTextureWidth();
|
|
||||||
|
|
||||||
int[] pixels = new int[lightMapWidth * lightMapHeight];
|
|
||||||
for (int u = 0; u < lightMapWidth; u++)
|
|
||||||
{
|
|
||||||
for (int v = 0; v < lightMapWidth; v++)
|
|
||||||
{
|
|
||||||
// this could probably be kept as a int, but
|
|
||||||
// it is easier to test and see the colors when debugging this way.
|
|
||||||
// When creating a new release this should be changed to the int version.
|
|
||||||
Color c = LodUtil.intToColor(lightMap.getLightValue(u, v));
|
|
||||||
|
|
||||||
// these should both create a totally white image
|
|
||||||
// int col =
|
|
||||||
// Integer.MAX_VALUE;
|
|
||||||
// int col =
|
|
||||||
// 0b11111111 + // red
|
|
||||||
// (0b11111111 << 8) + // green
|
|
||||||
// (0b11111111 << 16) + // blue
|
|
||||||
// (0b11111111 << 24); // blue
|
|
||||||
|
|
||||||
int col =
|
|
||||||
((c.getRed() & 0xFF) << 16) | // blue
|
|
||||||
((c.getGreen() & 0xFF) << 8) | // green
|
|
||||||
((c.getBlue() & 0xFF)) | // red
|
|
||||||
((c.getAlpha() & 0xFF) << 24); // alpha
|
|
||||||
|
|
||||||
// 2D array stored in a 1D array.
|
|
||||||
// Thank you Tim from College ;)
|
|
||||||
pixels[u * lightMapWidth + v] = col;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return pixels;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getLightmapTextureHeight()
|
|
||||||
{
|
|
||||||
int height = -1;
|
|
||||||
|
|
||||||
LightTexture lightTexture = GAME_RENDERER.lightTexture();
|
|
||||||
if (lightTexture != null)
|
|
||||||
{
|
|
||||||
NativeImage tex = lightTexture.lightPixels;
|
|
||||||
if (tex != null)
|
|
||||||
{
|
|
||||||
height = tex.getHeight();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return height;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getLightmapTextureWidth()
|
|
||||||
{
|
|
||||||
int width = -1;
|
|
||||||
|
|
||||||
LightTexture lightTexture = GAME_RENDERER.lightTexture();
|
|
||||||
if (lightTexture != null)
|
|
||||||
{
|
|
||||||
NativeImage tex = lightTexture.lightPixels;
|
|
||||||
if (tex != null)
|
|
||||||
{
|
|
||||||
width = tex.getWidth();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return width;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getLightmapGLFormat() {
|
|
||||||
int glFormat = -1;
|
|
||||||
|
|
||||||
LightTexture lightTexture = GAME_RENDERER.lightTexture();
|
|
||||||
if (lightTexture != null) {
|
|
||||||
NativeImage tex = lightTexture.lightPixels;
|
|
||||||
if (tex != null) {
|
|
||||||
glFormat = tex.format().glFormat();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return glFormat;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isFogStateSpecial() {
|
public boolean isFogStateSpecial() {
|
||||||
Entity entity = GAME_RENDERER.getMainCamera().getEntity();
|
#if PRE_MC_1_17_1
|
||||||
|
Camera camera = Minecraft.getInstance().gameRenderer.getMainCamera();
|
||||||
|
FluidState fluidState = camera.getFluidInCamera();
|
||||||
|
Entity entity = camera.getEntity();
|
||||||
|
boolean isUnderWater = (entity instanceof LivingEntity) && ((LivingEntity)entity).hasEffect(MobEffects.BLINDNESS);
|
||||||
|
isUnderWater |= fluidState.is(FluidTags.WATER);
|
||||||
|
isUnderWater |= fluidState.is(FluidTags.LAVA);
|
||||||
|
return isUnderWater;
|
||||||
|
#else
|
||||||
|
Entity entity = MC.gameRenderer.getMainCamera().getEntity();
|
||||||
boolean isBlind = (entity instanceof LivingEntity) && ((LivingEntity)entity).hasEffect(MobEffects.BLINDNESS);
|
boolean isBlind = (entity instanceof LivingEntity) && ((LivingEntity)entity).hasEffect(MobEffects.BLINDNESS);
|
||||||
return GAME_RENDERER.getMainCamera().getFluidInCamera() != FogType.NONE || isBlind;
|
return MC.gameRenderer.getMainCamera().getFluidInCamera() != FogType.NONE || isBlind;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean tryDisableVanillaFog() {
|
public boolean tryDisableVanillaFog() {
|
||||||
return true; // Handled via MixinFogRenderer in both forge and fabric
|
return true; // Handled via MixinFogRenderer in both forge and fabric
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void updateLightmap(NativeImage lightPixels) {
|
||||||
|
if (lightmap== null) {
|
||||||
|
lightmap = new LightMapWrapper();
|
||||||
|
}
|
||||||
|
lightmap.uploadLightmap(lightPixels);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,22 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
|
||||||
|
* licensed under the GNU LGPL v3 License.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2020-2022 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.lod.common.wrappers.minecraft;
|
package com.seibel.lod.common.wrappers.minecraft;
|
||||||
|
|
||||||
import com.seibel.lod.core.wrapperInterfaces.minecraft.IProfilerWrapper;
|
import com.seibel.lod.core.wrapperInterfaces.minecraft.IProfilerWrapper;
|
||||||
|
|||||||
@@ -1,7 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
|
||||||
|
* licensed under the GNU LGPL v3 License.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2020-2022 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.lod.common.wrappers.misc;
|
package com.seibel.lod.common.wrappers.misc;
|
||||||
|
|
||||||
import com.mojang.blaze3d.platform.NativeImage;
|
import com.mojang.blaze3d.platform.NativeImage;
|
||||||
import com.seibel.lod.core.wrapperInterfaces.misc.ILightMapWrapper;
|
import com.seibel.lod.core.wrapperInterfaces.misc.ILightMapWrapper;
|
||||||
|
import net.minecraft.client.renderer.LightTexture;
|
||||||
|
import org.lwjgl.opengl.GL;
|
||||||
|
import org.lwjgl.opengl.GL32;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author James Seibel
|
* @author James Seibel
|
||||||
@@ -9,21 +33,39 @@ import com.seibel.lod.core.wrapperInterfaces.misc.ILightMapWrapper;
|
|||||||
*/
|
*/
|
||||||
public class LightMapWrapper implements ILightMapWrapper
|
public class LightMapWrapper implements ILightMapWrapper
|
||||||
{
|
{
|
||||||
static NativeImage lightMap = null;
|
private int textureId = 0;
|
||||||
|
|
||||||
public LightMapWrapper(NativeImage newLightMap)
|
public LightMapWrapper()
|
||||||
{
|
{
|
||||||
lightMap = newLightMap;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void setLightMap(NativeImage newLightMap)
|
private void createLightmap(NativeImage image)
|
||||||
{
|
{
|
||||||
lightMap = newLightMap;
|
textureId = GL32.glGenTextures();
|
||||||
|
GL32.glBindTexture(GL32.GL_TEXTURE_2D, 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void uploadLightmap(NativeImage image)
|
||||||
|
{
|
||||||
|
int currentBind = GL32.glGetInteger(GL32.GL_TEXTURE_BINDING_2D);
|
||||||
|
GL32.glBindTexture(GL32.GL_TEXTURE_2D, textureId);
|
||||||
|
if (textureId == 0) {
|
||||||
|
createLightmap(image);
|
||||||
|
}
|
||||||
|
// NativeImage::upload(int levelOfDetail, int xOffset, int yOffset, bool shouldCleanup?)
|
||||||
|
image.upload(0, 0, 0, false);
|
||||||
|
GL32.glBindTexture(GL32.GL_TEXTURE_2D, currentBind);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getLightValue(int skyLight, int blockLight)
|
public void bind() {
|
||||||
{
|
GL32.glBindTexture(GL32.GL_TEXTURE_2D, textureId);
|
||||||
return lightMap.getPixelRGBA(skyLight, blockLight);
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void unbind() {
|
||||||
|
GL32.glBindTexture(GL32.GL_TEXTURE_2D, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,162 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of the Distant Horizon mod (formerly the LOD Mod),
|
|
||||||
* licensed under the GNU GPL v3 License.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2020 James Seibel
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU 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 General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.seibel.lod.common.wrappers.world;
|
|
||||||
|
|
||||||
import java.awt.Color;
|
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
|
||||||
import java.util.concurrent.ConcurrentMap;
|
|
||||||
|
|
||||||
import com.seibel.lod.core.util.LodUtil;
|
|
||||||
import com.seibel.lod.core.wrapperInterfaces.world.IBiomeWrapper;
|
|
||||||
|
|
||||||
import net.minecraft.world.level.biome.Biome;
|
|
||||||
import net.minecraft.world.level.block.Blocks;
|
|
||||||
import net.minecraft.world.level.material.MaterialColor;
|
|
||||||
|
|
||||||
//This class wraps the minecraft BlockPos.Mutable (and BlockPos) class
|
|
||||||
public class BiomeWrapper implements IBiomeWrapper
|
|
||||||
{
|
|
||||||
|
|
||||||
public static final ConcurrentMap<Biome, BiomeWrapper> biomeWrapperMap = new ConcurrentHashMap<>();
|
|
||||||
private final Biome biome;
|
|
||||||
|
|
||||||
public BiomeWrapper(Biome biome)
|
|
||||||
{
|
|
||||||
this.biome = biome;
|
|
||||||
}
|
|
||||||
|
|
||||||
static public IBiomeWrapper getBiomeWrapper(Biome biome)
|
|
||||||
{
|
|
||||||
//first we check if the biome has already been wrapped
|
|
||||||
if(biomeWrapperMap.containsKey(biome) && biomeWrapperMap.get(biome) != null)
|
|
||||||
return biomeWrapperMap.get(biome);
|
|
||||||
|
|
||||||
|
|
||||||
//if it hasn't been created yet, we create it and save it in the map
|
|
||||||
BiomeWrapper biomeWrapper = new BiomeWrapper(biome);
|
|
||||||
biomeWrapperMap.put(biome, biomeWrapper);
|
|
||||||
|
|
||||||
//we return the newly created wrapper
|
|
||||||
return biomeWrapper;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/** Returns a color int for the given biome. */
|
|
||||||
@Override
|
|
||||||
public int getColorForBiome(int x, int z)
|
|
||||||
{
|
|
||||||
int colorInt;
|
|
||||||
|
|
||||||
switch (biome.biomeCategory)
|
|
||||||
{
|
|
||||||
|
|
||||||
case NETHER:
|
|
||||||
colorInt = Blocks.NETHERRACK.defaultBlockState().getMaterial().getColor().col;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case THEEND:
|
|
||||||
colorInt = Blocks.END_STONE.defaultBlockState().getMaterial().getColor().col;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case BEACH:
|
|
||||||
case DESERT:
|
|
||||||
colorInt = Blocks.SAND.defaultBlockState().getMaterial().getColor().col;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case EXTREME_HILLS:
|
|
||||||
colorInt = Blocks.STONE.defaultMaterialColor().col;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MUSHROOM:
|
|
||||||
colorInt = MaterialColor.COLOR_LIGHT_GRAY.col;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ICY:
|
|
||||||
colorInt = Blocks.SNOW.defaultMaterialColor().col;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MESA:
|
|
||||||
colorInt = Blocks.RED_SAND.defaultMaterialColor().col;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case OCEAN:
|
|
||||||
case RIVER:
|
|
||||||
colorInt = biome.getWaterColor();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case NONE:
|
|
||||||
case FOREST:
|
|
||||||
case TAIGA:
|
|
||||||
case JUNGLE:
|
|
||||||
case PLAINS:
|
|
||||||
case SAVANNA:
|
|
||||||
case SWAMP:
|
|
||||||
default:
|
|
||||||
Color tmp = LodUtil.intToColor(biome.getGrassColor(x, z));
|
|
||||||
tmp = tmp.darker();
|
|
||||||
colorInt = LodUtil.colorToInt(tmp);
|
|
||||||
break;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return colorInt;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public String getName()
|
|
||||||
{
|
|
||||||
return biome.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getGrassTint(int x, int z)
|
|
||||||
{
|
|
||||||
return biome.getGrassColor(x, z);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getFolliageTint()
|
|
||||||
{
|
|
||||||
return biome.getFoliageColor();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getWaterTint()
|
|
||||||
{
|
|
||||||
return biome.getWaterColor();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override public boolean equals(Object obj)
|
|
||||||
{
|
|
||||||
if (this == obj)
|
|
||||||
return true;
|
|
||||||
if (!(obj instanceof BiomeWrapper))
|
|
||||||
return false;
|
|
||||||
BiomeWrapper that = (BiomeWrapper) obj;
|
|
||||||
return Objects.equals(biome, that.biome);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public int hashCode()
|
|
||||||
{
|
|
||||||
return Objects.hash(biome);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,163 @@
|
|||||||
|
package com.seibel.lod.common.wrappers.world;
|
||||||
|
|
||||||
|
import com.seibel.lod.api.enums.worldGeneration.EDhApiLevelType;
|
||||||
|
import com.seibel.lod.api.interfaces.world.IDhApiDimensionTypeWrapper;
|
||||||
|
import com.seibel.lod.common.wrappers.McObjectConverter;
|
||||||
|
import com.seibel.lod.common.wrappers.block.BiomeWrapper;
|
||||||
|
import com.seibel.lod.common.wrappers.block.BlockStateWrapper;
|
||||||
|
import com.seibel.lod.common.wrappers.block.cache.ClientBlockDetailMap;
|
||||||
|
import com.seibel.lod.common.wrappers.chunk.ChunkWrapper;
|
||||||
|
import com.seibel.lod.common.wrappers.minecraft.MinecraftClientWrapper;
|
||||||
|
import com.seibel.lod.core.logging.DhLoggerBuilder;
|
||||||
|
import com.seibel.lod.core.pos.DhBlockPos;
|
||||||
|
import com.seibel.lod.core.pos.DhChunkPos;
|
||||||
|
import com.seibel.lod.core.wrapperInterfaces.block.IBlockStateWrapper;
|
||||||
|
import com.seibel.lod.core.wrapperInterfaces.chunk.IChunkWrapper;
|
||||||
|
import com.seibel.lod.core.wrapperInterfaces.world.IBiomeWrapper;
|
||||||
|
import com.seibel.lod.core.wrapperInterfaces.world.IClientLevelWrapper;
|
||||||
|
import com.seibel.lod.core.wrapperInterfaces.world.IServerLevelWrapper;
|
||||||
|
import net.minecraft.client.multiplayer.ClientLevel;
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.world.level.LightLayer;
|
||||||
|
import net.minecraft.world.level.chunk.ChunkAccess;
|
||||||
|
import net.minecraft.world.level.chunk.ChunkSource;
|
||||||
|
import net.minecraft.world.level.chunk.ChunkStatus;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @version 2022-9-16
|
||||||
|
*/
|
||||||
|
public class ClientLevelWrapper implements IClientLevelWrapper
|
||||||
|
{
|
||||||
|
private static final Logger LOGGER = DhLoggerBuilder.getLogger(ClientLevelWrapper.class.getSimpleName());
|
||||||
|
private static final ConcurrentHashMap<ClientLevel, ClientLevelWrapper>
|
||||||
|
levelWrapperMap = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
public static ClientLevelWrapper getWrapper(ClientLevel level) {
|
||||||
|
return levelWrapperMap.computeIfAbsent(level, ClientLevelWrapper::new);
|
||||||
|
}
|
||||||
|
public static void closeWrapper(ClientLevel level)
|
||||||
|
{
|
||||||
|
levelWrapperMap.remove(level);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ClientLevelWrapper(ClientLevel level) {
|
||||||
|
this.level = level;
|
||||||
|
}
|
||||||
|
final ClientLevel level;
|
||||||
|
ClientBlockDetailMap blockMap = new ClientBlockDetailMap(this);
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public IServerLevelWrapper tryGetServerSideWrapper() {
|
||||||
|
try {
|
||||||
|
return ServerLevelWrapper.getWrapper(MinecraftClientWrapper.INSTANCE.mc.getSingleplayerServer().getPlayerList()
|
||||||
|
.getPlayer(MinecraftClientWrapper.INSTANCE.mc.player.getUUID()).getLevel());
|
||||||
|
} catch (Exception e) {
|
||||||
|
LOGGER.error("Failed to get server side wrapper for client level {}.", level);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static void cleanCheck() {
|
||||||
|
if (!levelWrapperMap.isEmpty()) {
|
||||||
|
LOGGER.warn("{} client levels havn't been freed!", levelWrapperMap.size());
|
||||||
|
levelWrapperMap.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int computeBaseColor(DhBlockPos pos, IBiomeWrapper biome, IBlockStateWrapper blockState) {
|
||||||
|
return blockMap.getColor(((BlockStateWrapper)blockState).blockState,
|
||||||
|
(BiomeWrapper)biome, pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IDhApiDimensionTypeWrapper getDimensionType()
|
||||||
|
{
|
||||||
|
return DimensionTypeWrapper.getDimensionTypeWrapper(level.dimensionType());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EDhApiLevelType getLevelType() { return EDhApiLevelType.CLIENT_LEVEL; }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getBlockLight(int x, int y, int z)
|
||||||
|
{
|
||||||
|
return level.getBrightness(LightLayer.BLOCK, new BlockPos(x,y,z));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getSkyLight(int x, int y, int z)
|
||||||
|
{
|
||||||
|
return level.getBrightness(LightLayer.SKY, new BlockPos(x,y,z));
|
||||||
|
}
|
||||||
|
|
||||||
|
public ClientLevel getLevel()
|
||||||
|
{
|
||||||
|
return level;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasCeiling() {
|
||||||
|
return level.dimensionType().hasCeiling();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasSkyLight() {
|
||||||
|
return level.dimensionType().hasSkyLight();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getHeight() {
|
||||||
|
return level.getHeight();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMinHeight()
|
||||||
|
{
|
||||||
|
#if PRE_MC_1_17_1
|
||||||
|
return 0;
|
||||||
|
#else
|
||||||
|
return level.getMinBuildHeight();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IChunkWrapper tryGetChunk(DhChunkPos pos) {
|
||||||
|
if (!level.hasChunk(pos.x, pos.z)) return null;
|
||||||
|
ChunkAccess chunk = level.getChunk(pos.getX(), pos.getZ(), ChunkStatus.EMPTY, false);
|
||||||
|
if (chunk == null) return null;
|
||||||
|
return new ChunkWrapper(chunk, level, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasChunkLoaded(int chunkX, int chunkZ) {
|
||||||
|
ChunkSource source = level.getChunkSource();
|
||||||
|
return source.hasChunk(chunkX, chunkZ);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IBlockStateWrapper getBlockState(DhBlockPos pos) {
|
||||||
|
return BlockStateWrapper.fromBlockState(level.getBlockState(McObjectConverter.Convert(pos)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IBiomeWrapper getBiome(DhBlockPos pos) {
|
||||||
|
return BiomeWrapper.getBiomeWrapper(level.getBiome(McObjectConverter.Convert(pos)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ClientLevel getWrappedMcObject_UNSAFE()
|
||||||
|
{
|
||||||
|
return level;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Wrapped{" + level.toString() + "@" + getDimensionType().getDimensionName() + "}";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+33
-8
@@ -1,19 +1,19 @@
|
|||||||
/*
|
/*
|
||||||
* This file is part of the Distant Horizon mod (formerly the LOD Mod),
|
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
|
||||||
* licensed under the GNU GPL v3 License.
|
* licensed under the GNU LGPL v3 License.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2020 James Seibel
|
* Copyright (C) 2020-2022 James Seibel
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
* the Free Software Foundation, version 3.
|
* the Free Software Foundation, version 3.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU Lesser General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* 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/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -22,14 +22,15 @@ package com.seibel.lod.common.wrappers.world;
|
|||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.ConcurrentMap;
|
import java.util.concurrent.ConcurrentMap;
|
||||||
|
|
||||||
|
import com.seibel.lod.api.interfaces.world.IDhApiDimensionTypeWrapper;
|
||||||
import com.seibel.lod.core.wrapperInterfaces.world.IDimensionTypeWrapper;
|
import com.seibel.lod.core.wrapperInterfaces.world.IDimensionTypeWrapper;
|
||||||
|
|
||||||
|
import net.minecraft.world.level.Level;
|
||||||
import net.minecraft.world.level.dimension.DimensionType;
|
import net.minecraft.world.level.dimension.DimensionType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @author James Seibel
|
* @author James Seibel
|
||||||
* @version 11-21-2021
|
* @version 2022-9-16
|
||||||
*/
|
*/
|
||||||
public class DimensionTypeWrapper implements IDimensionTypeWrapper
|
public class DimensionTypeWrapper implements IDimensionTypeWrapper
|
||||||
{
|
{
|
||||||
@@ -79,4 +80,28 @@ public class DimensionTypeWrapper implements IDimensionTypeWrapper
|
|||||||
{
|
{
|
||||||
return dimensionType.hasSkyLight();
|
return dimensionType.hasSkyLight();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getWrappedMcObject_UNSAFE()
|
||||||
|
{
|
||||||
|
return this.dimensionType;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj)
|
||||||
|
{
|
||||||
|
if (obj.getClass() != DimensionTypeWrapper.class)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DimensionTypeWrapper other = (DimensionTypeWrapper) obj;
|
||||||
|
return other.getDimensionName().equals(this.getDimensionName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,189 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
|
||||||
|
* licensed under the GNU LGPL v3 License.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2020-2022 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.lod.common.wrappers.world;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
import com.seibel.lod.api.enums.worldGeneration.EDhApiLevelType;
|
||||||
|
import com.seibel.lod.common.wrappers.McObjectConverter;
|
||||||
|
import com.seibel.lod.common.wrappers.block.BiomeWrapper;
|
||||||
|
import com.seibel.lod.common.wrappers.block.BlockStateWrapper;
|
||||||
|
import com.seibel.lod.common.wrappers.block.cache.ServerBlockDetailMap;
|
||||||
|
import com.seibel.lod.common.wrappers.minecraft.MinecraftClientWrapper;
|
||||||
|
import com.seibel.lod.core.logging.DhLoggerBuilder;
|
||||||
|
import com.seibel.lod.core.pos.DhBlockPos;
|
||||||
|
import com.seibel.lod.core.pos.DhChunkPos;
|
||||||
|
import com.seibel.lod.core.wrapperInterfaces.block.IBlockStateWrapper;
|
||||||
|
import com.seibel.lod.core.wrapperInterfaces.chunk.IChunkWrapper;
|
||||||
|
import com.seibel.lod.core.wrapperInterfaces.world.IBiomeWrapper;
|
||||||
|
import com.seibel.lod.core.wrapperInterfaces.world.IClientLevelWrapper;
|
||||||
|
import com.seibel.lod.common.wrappers.chunk.ChunkWrapper;
|
||||||
|
|
||||||
|
import com.seibel.lod.core.wrapperInterfaces.world.IServerLevelWrapper;
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
|
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.ChunkSource;
|
||||||
|
import net.minecraft.world.level.chunk.ChunkStatus;
|
||||||
|
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @version 2022-9-16
|
||||||
|
*/
|
||||||
|
public class ServerLevelWrapper implements IServerLevelWrapper
|
||||||
|
{
|
||||||
|
private static final Logger LOGGER = DhLoggerBuilder.getLogger(ServerLevelWrapper.class.getSimpleName());
|
||||||
|
private static final ConcurrentHashMap<ServerLevel, ServerLevelWrapper>
|
||||||
|
levelWrapperMap = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
public static ServerLevelWrapper getWrapper(ServerLevel level)
|
||||||
|
{
|
||||||
|
return levelWrapperMap.computeIfAbsent(level, ServerLevelWrapper::new);
|
||||||
|
}
|
||||||
|
public static void closeWrapper(ServerLevel level)
|
||||||
|
{
|
||||||
|
levelWrapperMap.remove(level);
|
||||||
|
}
|
||||||
|
public static void cleanCheck() {
|
||||||
|
if (!levelWrapperMap.isEmpty()) {
|
||||||
|
LOGGER.warn("{} server levels havn't been freed!", levelWrapperMap.size());
|
||||||
|
levelWrapperMap.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final ServerLevel level;
|
||||||
|
ServerBlockDetailMap blockMap = new ServerBlockDetailMap(this);
|
||||||
|
|
||||||
|
public ServerLevelWrapper(ServerLevel level)
|
||||||
|
{
|
||||||
|
this.level = level;
|
||||||
|
}
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public IClientLevelWrapper tryGetClientSideWrapper() {
|
||||||
|
try {
|
||||||
|
MinecraftClientWrapper client = MinecraftClientWrapper.INSTANCE;
|
||||||
|
return ClientLevelWrapper.getWrapper(client.mc.level);
|
||||||
|
} catch (Exception e) {
|
||||||
|
LOGGER.error("Failed to get client side wrapper for server level {}.", level);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public File getSaveFolder()
|
||||||
|
{
|
||||||
|
return level.getChunkSource().getDataStorage().dataFolder;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DimensionTypeWrapper getDimensionType()
|
||||||
|
{
|
||||||
|
return DimensionTypeWrapper.getDimensionTypeWrapper(level.dimensionType());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EDhApiLevelType getLevelType() { return EDhApiLevelType.CLIENT_LEVEL; }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getBlockLight(int x, int y, int z)
|
||||||
|
{
|
||||||
|
return level.getBrightness(LightLayer.BLOCK, new BlockPos(x,y,z));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getSkyLight(int x, int y, int z)
|
||||||
|
{
|
||||||
|
return level.getBrightness(LightLayer.SKY, new BlockPos(x,y,z));
|
||||||
|
}
|
||||||
|
|
||||||
|
public ServerLevel getLevel()
|
||||||
|
{
|
||||||
|
return level;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasCeiling()
|
||||||
|
{
|
||||||
|
return level.dimensionType().hasCeiling();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasSkyLight()
|
||||||
|
{
|
||||||
|
return level.dimensionType().hasSkyLight();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getHeight()
|
||||||
|
{
|
||||||
|
return level.getHeight();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMinHeight()
|
||||||
|
{
|
||||||
|
#if PRE_MC_1_17_1
|
||||||
|
return 0;
|
||||||
|
#else
|
||||||
|
return level.getMinBuildHeight();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public IChunkWrapper tryGetChunk(DhChunkPos pos) {
|
||||||
|
if (!level.hasChunk(pos.x, pos.z)) return null;
|
||||||
|
ChunkAccess chunk = level.getChunk(pos.getX(), pos.getZ(), ChunkStatus.EMPTY, false);
|
||||||
|
if (chunk == null) return null;
|
||||||
|
return new ChunkWrapper(chunk, level, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasChunkLoaded(int chunkX, int chunkZ) {
|
||||||
|
// world.hasChunk(chunkX, chunkZ); THIS DOES NOT WORK FOR CLIENT LEVEL CAUSE MOJANG ALWAYS RETURN TRUE FOR THAT!
|
||||||
|
ChunkSource source = level.getChunkSource();
|
||||||
|
return source.hasChunk(chunkX, chunkZ);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IBlockStateWrapper getBlockState(DhBlockPos pos) {
|
||||||
|
return BlockStateWrapper.fromBlockState(level.getBlockState(McObjectConverter.Convert(pos)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IBiomeWrapper getBiome(DhBlockPos pos) {
|
||||||
|
return BiomeWrapper.getBiomeWrapper(level.getBiome(McObjectConverter.Convert(pos)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ServerLevel getWrappedMcObject_UNSAFE()
|
||||||
|
{
|
||||||
|
return level;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Wrapped{" + level.toString() + "@" + getDimensionType().getDimensionName() + "}";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,187 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of the Distant Horizon mod (formerly the LOD Mod),
|
|
||||||
* licensed under the GNU GPL v3 License.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2020 James Seibel
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU 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 General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.seibel.lod.common.wrappers.world;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
|
||||||
import java.util.concurrent.ConcurrentMap;
|
|
||||||
|
|
||||||
import com.seibel.lod.core.enums.WorldType;
|
|
||||||
import com.seibel.lod.core.wrapperInterfaces.chunk.AbstractChunkPosWrapper;
|
|
||||||
import com.seibel.lod.core.wrapperInterfaces.chunk.IChunkWrapper;
|
|
||||||
import com.seibel.lod.core.wrapperInterfaces.world.IWorldWrapper;
|
|
||||||
import com.seibel.lod.common.wrappers.chunk.ChunkWrapper;
|
|
||||||
|
|
||||||
import net.minecraft.client.multiplayer.ClientLevel;
|
|
||||||
import net.minecraft.core.BlockPos;
|
|
||||||
import net.minecraft.server.level.ServerChunkCache;
|
|
||||||
import net.minecraft.server.level.ServerLevel;
|
|
||||||
import net.minecraft.world.level.LevelAccessor;
|
|
||||||
import net.minecraft.world.level.LightLayer;
|
|
||||||
import net.minecraft.world.level.chunk.ChunkAccess;
|
|
||||||
import net.minecraft.world.level.chunk.ChunkSource;
|
|
||||||
import net.minecraft.world.level.chunk.ChunkStatus;
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author James Seibel
|
|
||||||
* @author ??
|
|
||||||
* @version 11-21-2021
|
|
||||||
*/
|
|
||||||
public class WorldWrapper implements IWorldWrapper
|
|
||||||
{
|
|
||||||
private static final ConcurrentMap<LevelAccessor, WorldWrapper> worldWrapperMap = new ConcurrentHashMap<>();
|
|
||||||
private final LevelAccessor world;
|
|
||||||
public final WorldType worldType;
|
|
||||||
|
|
||||||
|
|
||||||
public WorldWrapper(LevelAccessor newWorld)
|
|
||||||
{
|
|
||||||
world = newWorld;
|
|
||||||
|
|
||||||
if (world.getClass() == ServerLevel.class)
|
|
||||||
worldType = WorldType.ServerWorld;
|
|
||||||
else if (world.getClass() == ClientLevel.class)
|
|
||||||
worldType = WorldType.ClientWorld;
|
|
||||||
else
|
|
||||||
worldType = WorldType.Unknown;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
public static WorldWrapper getWorldWrapper(LevelAccessor world)
|
|
||||||
{
|
|
||||||
if (world == null) return null;
|
|
||||||
//first we check if the biome has already been wrapped
|
|
||||||
if(worldWrapperMap.containsKey(world) && worldWrapperMap.get(world) != null)
|
|
||||||
return worldWrapperMap.get(world);
|
|
||||||
|
|
||||||
|
|
||||||
//if it hasn't been created yet, we create it and save it in the map
|
|
||||||
WorldWrapper worldWrapper = new WorldWrapper(world);
|
|
||||||
worldWrapperMap.put(world, worldWrapper);
|
|
||||||
|
|
||||||
//we return the newly created wrapper
|
|
||||||
return worldWrapper;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void clearMap()
|
|
||||||
{
|
|
||||||
worldWrapperMap.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public WorldType getWorldType()
|
|
||||||
{
|
|
||||||
return worldType;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public DimensionTypeWrapper getDimensionType()
|
|
||||||
{
|
|
||||||
return DimensionTypeWrapper.getDimensionTypeWrapper(world.dimensionType());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getBlockLight(int x, int y, int z)
|
|
||||||
{
|
|
||||||
return world.getBrightness(LightLayer.BLOCK, new BlockPos(x,y,z));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getSkyLight(int x, int y, int z)
|
|
||||||
{
|
|
||||||
return world.getBrightness(LightLayer.SKY, new BlockPos(x,y,z));
|
|
||||||
}
|
|
||||||
|
|
||||||
public LevelAccessor getWorld()
|
|
||||||
{
|
|
||||||
return world;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean hasCeiling()
|
|
||||||
{
|
|
||||||
return world.dimensionType().hasCeiling();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean hasSkyLight()
|
|
||||||
{
|
|
||||||
return world.dimensionType().hasSkyLight();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getHeight()
|
|
||||||
{
|
|
||||||
return world.getHeight();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public short getMinHeight()
|
|
||||||
{
|
|
||||||
return (short) world.getMinBuildHeight();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @throws UnsupportedOperationException if the WorldWrapper isn't for a ServerWorld */
|
|
||||||
@Override
|
|
||||||
public File getSaveFolder() throws UnsupportedOperationException
|
|
||||||
{
|
|
||||||
if (worldType != WorldType.ServerWorld)
|
|
||||||
throw new UnsupportedOperationException("getSaveFolder can only be called for ServerWorlds.");
|
|
||||||
|
|
||||||
ServerChunkCache chunkSource = ((ServerLevel) world).getChunkSource();
|
|
||||||
return chunkSource.getDataStorage().dataFolder;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/** @throws UnsupportedOperationException if the WorldWrapper isn't for a ServerWorld */
|
|
||||||
public ServerLevel getServerWorld() throws UnsupportedOperationException
|
|
||||||
{
|
|
||||||
if (worldType != WorldType.ServerWorld)
|
|
||||||
throw new UnsupportedOperationException("getSaveFolder can only be called for ServerWorlds.");
|
|
||||||
|
|
||||||
return (ServerLevel) world;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getSeaLevel()
|
|
||||||
{
|
|
||||||
// TODO this is depreciated, what should we use instead?
|
|
||||||
return world.getSeaLevel();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public IChunkWrapper tryGetChunk(AbstractChunkPosWrapper pos) {
|
|
||||||
ChunkAccess chunk = world.getChunk(pos.getX(), pos.getZ(), ChunkStatus.EMPTY, false);
|
|
||||||
if (chunk == null) return null;
|
|
||||||
return new ChunkWrapper(chunk, world);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean hasChunkLoaded(int chunkX, int chunkZ) {
|
|
||||||
// world.hasChunk(chunkX, chunkZ); THIS DOES NOT WORK FOR CLIENT LEVEL CAUSE MOJANG ALWAYS RETURN TRUE FOR THAT!
|
|
||||||
ChunkSource source = world.getChunkSource();
|
|
||||||
return source.hasChunk(chunkX, chunkZ);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
+191
-261
@@ -1,49 +1,53 @@
|
|||||||
/*
|
/*
|
||||||
* This file is part of the Distant Horizon mod (formerly the LOD Mod),
|
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
|
||||||
* licensed under the GNU GPL v3 License.
|
* licensed under the GNU LGPL v3 License.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2021 Tom Lee (TomTheFurry)
|
* Copyright (C) 2021 Tom Lee (TomTheFurry)
|
||||||
|
* Copyright (C) 2020-2022 James Seibel
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
* the Free Software Foundation, version 3.
|
* the Free Software Foundation, version 3.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU Lesser General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* 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/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
package com.seibel.lod.common.wrappers.worldGeneration;
|
package com.seibel.lod.common.wrappers.worldGeneration;
|
||||||
|
|
||||||
import com.seibel.lod.core.api.ApiShared;
|
import com.seibel.lod.api.enums.worldGeneration.EDhApiDistantGeneratorMode;
|
||||||
import com.seibel.lod.core.builders.lodBuilding.LodBuilder;
|
import com.seibel.lod.common.wrappers.world.ServerLevelWrapper;
|
||||||
import com.seibel.lod.core.builders.lodBuilding.LodBuilderConfig;
|
import com.seibel.lod.core.level.IDhServerLevel;
|
||||||
import com.seibel.lod.core.enums.config.DistanceGenerationMode;
|
import com.seibel.lod.core.config.Config;
|
||||||
import com.seibel.lod.core.enums.config.LightGenerationMode;
|
import com.seibel.lod.api.enums.config.ELightGenerationMode;
|
||||||
import com.seibel.lod.core.handlers.dependencyInjection.SingletonHandler;
|
import com.seibel.lod.core.logging.ConfigBasedLogger;
|
||||||
import com.seibel.lod.core.objects.lod.LodDimension;
|
import com.seibel.lod.core.logging.ConfigBasedSpamLogger;
|
||||||
|
import com.seibel.lod.core.pos.DhChunkPos;
|
||||||
|
import com.seibel.lod.core.util.objects.EventTimer;
|
||||||
|
import com.seibel.lod.core.util.LodUtil;
|
||||||
import com.seibel.lod.core.util.gridList.ArrayGridList;
|
import com.seibel.lod.core.util.gridList.ArrayGridList;
|
||||||
import com.seibel.lod.core.util.LodThreadFactory;
|
import com.seibel.lod.core.util.objects.LodThreadFactory;
|
||||||
import com.seibel.lod.core.wrapperInterfaces.config.ILodConfigWrapperSingleton;
|
import com.seibel.lod.core.wrapperInterfaces.chunk.IChunkWrapper;
|
||||||
import com.seibel.lod.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
|
|
||||||
import com.seibel.lod.core.wrapperInterfaces.world.IWorldWrapper;
|
|
||||||
import com.seibel.lod.core.wrapperInterfaces.worldGeneration.AbstractBatchGenerationEnvionmentWrapper;
|
import com.seibel.lod.core.wrapperInterfaces.worldGeneration.AbstractBatchGenerationEnvionmentWrapper;
|
||||||
|
|
||||||
import java.time.Duration;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
import com.seibel.lod.common.wrappers.DependencySetupDoneCheck;
|
import com.seibel.lod.common.wrappers.DependencySetupDoneCheck;
|
||||||
import com.seibel.lod.common.wrappers.chunk.ChunkWrapper;
|
import com.seibel.lod.common.wrappers.chunk.ChunkWrapper;
|
||||||
import com.seibel.lod.common.wrappers.world.WorldWrapper;
|
|
||||||
import com.seibel.lod.common.wrappers.worldGeneration.mimicObject.ChunkLoader;
|
import com.seibel.lod.common.wrappers.worldGeneration.mimicObject.ChunkLoader;
|
||||||
import com.seibel.lod.common.wrappers.worldGeneration.mimicObject.LightGetterAdaptor;
|
import com.seibel.lod.common.wrappers.worldGeneration.mimicObject.LightGetterAdaptor;
|
||||||
import com.seibel.lod.common.wrappers.worldGeneration.mimicObject.LightedWorldGenRegion;
|
import com.seibel.lod.common.wrappers.worldGeneration.mimicObject.LightedWorldGenRegion;
|
||||||
@@ -70,6 +74,7 @@ import net.minecraft.world.level.levelgen.NoiseBasedChunkGenerator;
|
|||||||
import net.minecraft.core.Registry;
|
import net.minecraft.core.Registry;
|
||||||
import net.minecraft.nbt.CompoundTag;
|
import net.minecraft.nbt.CompoundTag;
|
||||||
import net.minecraft.world.level.lighting.LevelLightEngine;
|
import net.minecraft.world.level.lighting.LevelLightEngine;
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Total: 3.135214124s
|
Total: 3.135214124s
|
||||||
@@ -87,125 +92,67 @@ Lod Generation: 0.269023348s
|
|||||||
|
|
||||||
public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnvionmentWrapper
|
public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnvionmentWrapper
|
||||||
{
|
{
|
||||||
public static final boolean ENABLE_PERF_LOGGING = false;
|
public static final ConfigBasedSpamLogger PREF_LOGGER =
|
||||||
public static final boolean ENABLE_EVENT_LOGGING = false;
|
new ConfigBasedSpamLogger(LogManager.getLogger("LodWorldGen"),
|
||||||
public static final boolean ENABLE_LOAD_EVENT_LOGGING = false;
|
() -> Config.Client.Advanced.Debugging.DebugSwitch.logWorldGenPerformance.get(),1);
|
||||||
|
public static final ConfigBasedLogger EVENT_LOGGER =
|
||||||
|
new ConfigBasedLogger(LogManager.getLogger("LodWorldGen"),
|
||||||
|
() -> Config.Client.Advanced.Debugging.DebugSwitch.logWorldGenEvent.get());
|
||||||
|
public static final ConfigBasedLogger LOAD_LOGGER =
|
||||||
|
new ConfigBasedLogger(LogManager.getLogger("LodWorldGen"),
|
||||||
|
() -> Config.Client.Advanced.Debugging.DebugSwitch.logWorldGenLoadEvent.get());
|
||||||
|
|
||||||
//TODO: Make actual proper support for StarLight
|
//TODO: Make actual proper support for StarLight
|
||||||
|
|
||||||
public static class PrefEvent
|
|
||||||
{
|
|
||||||
long beginNano = 0;
|
|
||||||
long emptyNano = 0;
|
|
||||||
long structStartNano = 0;
|
|
||||||
long structRefNano = 0;
|
|
||||||
long biomeNano = 0;
|
|
||||||
long noiseNano = 0;
|
|
||||||
long surfaceNano = 0;
|
|
||||||
long carverNano = 0;
|
|
||||||
long featureNano = 0;
|
|
||||||
long lightNano = 0;
|
|
||||||
long endNano = 0;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString()
|
|
||||||
{
|
|
||||||
return "beginNano: " + beginNano + ",\n" +
|
|
||||||
"emptyNano: " + emptyNano + ",\n" +
|
|
||||||
"structStartNano: " + structStartNano + ",\n" +
|
|
||||||
"structRefNano: " + structRefNano + ",\n" +
|
|
||||||
"biomeNano: " + biomeNano + ",\n" +
|
|
||||||
"noiseNano: " + noiseNano + ",\n" +
|
|
||||||
"surfaceNano: " + surfaceNano + ",\n" +
|
|
||||||
"carverNano: " + carverNano + ",\n" +
|
|
||||||
"featureNano: " + featureNano + ",\n" +
|
|
||||||
"lightNano: " + lightNano + ",\n" +
|
|
||||||
"endNano: " + endNano + "\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class PerfCalculator
|
public static class PerfCalculator
|
||||||
{
|
{
|
||||||
|
private static final String[] TIME_NAMES = {
|
||||||
|
"total",
|
||||||
|
"setup",
|
||||||
|
"structStart",
|
||||||
|
"structRef",
|
||||||
|
"biome",
|
||||||
|
"noise",
|
||||||
|
"surface",
|
||||||
|
"carver",
|
||||||
|
"feature",
|
||||||
|
"light",
|
||||||
|
"cleanup",
|
||||||
|
//"lodCreation" (No longer used)
|
||||||
|
};
|
||||||
|
|
||||||
public static final int SIZE = 50;
|
public static final int SIZE = 50;
|
||||||
Rolling totalTime = new Rolling(SIZE);
|
ArrayList<Rolling> times = new ArrayList<>();
|
||||||
Rolling emptyTime = new Rolling(SIZE);
|
|
||||||
Rolling structStartTime = new Rolling(SIZE);
|
public PerfCalculator()
|
||||||
Rolling structRefTime = new Rolling(SIZE);
|
|
||||||
Rolling biomeTime = new Rolling(SIZE);
|
|
||||||
Rolling noiseTime = new Rolling(SIZE);
|
|
||||||
Rolling surfaceTime = new Rolling(SIZE);
|
|
||||||
Rolling carverTime = new Rolling(SIZE);
|
|
||||||
Rolling featureTime = new Rolling(SIZE);
|
|
||||||
Rolling lightTime = new Rolling(SIZE);
|
|
||||||
Rolling lodTime = new Rolling(SIZE);
|
|
||||||
|
|
||||||
public void recordEvent(PrefEvent e)
|
|
||||||
{
|
{
|
||||||
long preTime = e.beginNano;
|
for(int i = 0; i < 11; i++)
|
||||||
totalTime.add(e.endNano - preTime);
|
|
||||||
if (e.emptyNano != 0)
|
|
||||||
{
|
{
|
||||||
emptyTime.add(e.emptyNano - preTime);
|
times.add(new Rolling(SIZE));
|
||||||
preTime = e.emptyNano;
|
|
||||||
}
|
}
|
||||||
if (e.structStartNano != 0)
|
}
|
||||||
|
|
||||||
|
public void recordEvent(EventTimer event)
|
||||||
|
{
|
||||||
|
for (EventTimer.Event e : event.events)
|
||||||
{
|
{
|
||||||
structStartTime.add(e.structStartNano - preTime);
|
String name = e.name;
|
||||||
preTime = e.structStartNano;
|
int index = Arrays.asList(TIME_NAMES).indexOf(name);
|
||||||
}
|
if(index == -1) continue;
|
||||||
if (e.structRefNano != 0)
|
times.get(index).add(e.timeNs);
|
||||||
{
|
|
||||||
structRefTime.add(e.structRefNano - preTime);
|
|
||||||
preTime = e.structRefNano;
|
|
||||||
}
|
|
||||||
if (e.biomeNano != 0)
|
|
||||||
{
|
|
||||||
biomeTime.add(e.biomeNano - preTime);
|
|
||||||
preTime = e.biomeNano;
|
|
||||||
}
|
|
||||||
if (e.noiseNano != 0)
|
|
||||||
{
|
|
||||||
noiseTime.add(e.noiseNano - preTime);
|
|
||||||
preTime = e.noiseNano;
|
|
||||||
}
|
|
||||||
if (e.surfaceNano != 0)
|
|
||||||
{
|
|
||||||
surfaceTime.add(e.surfaceNano - preTime);
|
|
||||||
preTime = e.surfaceNano;
|
|
||||||
}
|
|
||||||
if (e.carverNano != 0)
|
|
||||||
{
|
|
||||||
carverTime.add(e.carverNano - preTime);
|
|
||||||
preTime = e.carverNano;
|
|
||||||
}
|
|
||||||
if (e.featureNano != 0)
|
|
||||||
{
|
|
||||||
featureTime.add(e.featureNano - preTime);
|
|
||||||
preTime = e.featureNano;
|
|
||||||
}
|
|
||||||
if (e.lightNano != 0)
|
|
||||||
{
|
|
||||||
lightTime.add(e.lightNano - preTime);
|
|
||||||
preTime = e.lightNano;
|
|
||||||
}
|
|
||||||
if (e.endNano != 0)
|
|
||||||
{
|
|
||||||
lodTime.add(e.endNano - preTime);
|
|
||||||
}
|
}
|
||||||
|
times.get(0).add(event.getTotalTimeNs());
|
||||||
}
|
}
|
||||||
|
|
||||||
public String toString()
|
public String toString()
|
||||||
{
|
{
|
||||||
return "Total: " + Duration.ofNanos((long) totalTime.getAverage()) + ", Empty/LoadChunk: "
|
StringBuilder sb = new StringBuilder();
|
||||||
+ Duration.ofNanos((long) emptyTime.getAverage()) + ", StructStart: "
|
for (int i = 0; i < times.size(); i++)
|
||||||
+ Duration.ofNanos((long) structStartTime.getAverage()) + ", StructRef: "
|
{
|
||||||
+ Duration.ofNanos((long) structRefTime.getAverage()) + ", Biome: "
|
if (times.get(i).getAverage() == 0) continue;
|
||||||
+ Duration.ofNanos((long) biomeTime.getAverage()) + ", Noise: "
|
sb.append(TIME_NAMES[i]).append(": ").append(times.get(i).getAverage()).append("\n");
|
||||||
+ Duration.ofNanos((long) noiseTime.getAverage()) + ", Surface: "
|
}
|
||||||
+ Duration.ofNanos((long) surfaceTime.getAverage()) + ", Carver: "
|
return sb.toString();
|
||||||
+ Duration.ofNanos((long) carverTime.getAverage()) + ", Feature: "
|
|
||||||
+ Duration.ofNanos((long) featureTime.getAverage()) + ", Light: "
|
|
||||||
+ Duration.ofNanos((long) lightTime.getAverage()) + ", Lod: "
|
|
||||||
+ Duration.ofNanos((long) lodTime.getAverage());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -224,8 +171,7 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
|
|||||||
public final StepLight stepLight = new StepLight(this);
|
public final StepLight stepLight = new StepLight(this);
|
||||||
public boolean unsafeThreadingRecorded = false;
|
public boolean unsafeThreadingRecorded = false;
|
||||||
//public boolean safeMode = false;
|
//public boolean safeMode = false;
|
||||||
private static final ILodConfigWrapperSingleton CONFIG = SingletonHandler.get(ILodConfigWrapperSingleton.class);
|
//private static final IMinecraftClientWrapper MC = SingletonHandler.get(IMinecraftClientWrapper.class);
|
||||||
private static final IMinecraftClientWrapper MC = SingletonHandler.get(IMinecraftClientWrapper.class);
|
|
||||||
public static final long EXCEPTION_TIMER_RESET_TIME = TimeUnit.NANOSECONDS.convert(1, TimeUnit.SECONDS);
|
public static final long EXCEPTION_TIMER_RESET_TIME = TimeUnit.NANOSECONDS.convert(1, TimeUnit.SECONDS);
|
||||||
public static final int EXCEPTION_COUNTER_TRIGGER = 20;
|
public static final int EXCEPTION_COUNTER_TRIGGER = 20;
|
||||||
public static final int RANGE_TO_RANGE_EMPTY_EXTENSION = 1;
|
public static final int RANGE_TO_RANGE_EMPTY_EXTENSION = 1;
|
||||||
@@ -245,13 +191,13 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
|
|||||||
}
|
}
|
||||||
|
|
||||||
public ExecutorService executors = Executors.newFixedThreadPool(
|
public ExecutorService executors = Executors.newFixedThreadPool(
|
||||||
CONFIG.client().advanced().threading().getNumberOfWorldGenerationThreads(), threadFactory);
|
Math.max(Config.Client.Advanced.Threading.numberOfWorldGenerationThreads.get().intValue(), 1),
|
||||||
|
threadFactory);
|
||||||
|
|
||||||
public <T> T joinSync(CompletableFuture<T> f) {
|
public <T> T joinSync(CompletableFuture<T> f) {
|
||||||
if (!unsafeThreadingRecorded && !f.isDone()) {
|
if (!unsafeThreadingRecorded && !f.isDone()) {
|
||||||
MC.sendChatMessage("\u00A74\u00A7l\u00A7uERROR: Distant Horizons: Unsafe Threading in Chunk Generator Detected!");
|
EVENT_LOGGER.error("Unsafe Threading in Chunk Generator: ", new RuntimeException("Concurrent future"));
|
||||||
MC.sendChatMessage("\u00A7eTo increase stability, it is recommended to set world generation threads count to 1.");
|
EVENT_LOGGER.error("To increase stability, it is recommended to set world generation threads count to 1.");
|
||||||
ApiShared.LOGGER.error("Unsafe Threading in Chunk Generator: ", new RuntimeException("Concurrent future"));
|
|
||||||
unsafeThreadingRecorded = true;
|
unsafeThreadingRecorded = true;
|
||||||
}
|
}
|
||||||
return f.join();
|
return f.join();
|
||||||
@@ -262,23 +208,7 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
|
|||||||
executors = Executors.newFixedThreadPool(newThreadCount,
|
executors = Executors.newFixedThreadPool(newThreadCount,
|
||||||
new LodThreadFactory("Gen-Worker-Thread", Thread.MIN_PRIORITY));
|
new LodThreadFactory("Gen-Worker-Thread", Thread.MIN_PRIORITY));
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean tryAddPoint(int px, int pz, int range, Steps target, boolean genAllDetails)
|
|
||||||
{
|
|
||||||
int boxSize = range * 2 + 1;
|
|
||||||
int x = Math.floorDiv(px, boxSize) * boxSize + range;
|
|
||||||
int z = Math.floorDiv(pz, boxSize) * boxSize + range;
|
|
||||||
|
|
||||||
for (GenerationEvent event : events)
|
|
||||||
{
|
|
||||||
if (event.tooClose(x, z, range))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// System.out.println(x + ", "+z);
|
|
||||||
events.add(new GenerationEvent(new ChunkPos(x, z), range, this, target, genAllDetails));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void updateAllFutures()
|
public void updateAllFutures()
|
||||||
{
|
{
|
||||||
if (unknownExceptionCount > 0) {
|
if (unknownExceptionCount > 0) {
|
||||||
@@ -286,38 +216,34 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
|
|||||||
unknownExceptionCount = 0;
|
unknownExceptionCount = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update all current out standing jobs
|
// Update all current out standing jobs
|
||||||
Iterator<GenerationEvent> iter = events.iterator();
|
Iterator<GenerationEvent> iter = events.iterator();
|
||||||
while (iter.hasNext())
|
while (iter.hasNext())
|
||||||
{
|
{
|
||||||
GenerationEvent event = iter.next();
|
GenerationEvent event = iter.next();
|
||||||
if (event.isCompleted())
|
if (event.future.isDone())
|
||||||
{
|
{
|
||||||
try
|
if (event.future.isCompletedExceptionally() && !event.future.isCancelled()) {
|
||||||
{
|
try {
|
||||||
event.join();
|
event.future.get(); // Should throw exception
|
||||||
}
|
LodUtil.assertNotReach();
|
||||||
catch (Throwable e)
|
} catch (Exception e) {
|
||||||
{
|
unknownExceptionCount++;
|
||||||
ApiShared.LOGGER.error("Batching World Generator: Event {} gotten an exception", event);
|
lastExceptionTriggerTime = System.nanoTime();
|
||||||
ApiShared.LOGGER.error("Exception: ", e);
|
EVENT_LOGGER.error("Batching World Generator: Event {} gotten an exception", event);
|
||||||
unknownExceptionCount++;
|
EVENT_LOGGER.error("Exception: ", e);
|
||||||
lastExceptionTriggerTime = System.nanoTime();
|
}
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
iter.remove();
|
|
||||||
}
|
}
|
||||||
|
iter.remove();
|
||||||
}
|
}
|
||||||
else if (event.hasTimeout(TIMEOUT_SECONDS, TimeUnit.SECONDS))
|
else if (event.hasTimeout(TIMEOUT_SECONDS, TimeUnit.SECONDS))
|
||||||
{
|
{
|
||||||
ApiShared.LOGGER.error("Batching World Generator: " + event + " timed out and terminated!");
|
EVENT_LOGGER.error("Batching World Generator: " + event + " timed out and terminated!");
|
||||||
ApiShared.LOGGER.info("Dump PrefEvent: " + event.pEvent);
|
EVENT_LOGGER.info("Dump PrefEvent: " + event.timer);
|
||||||
try
|
try {
|
||||||
{
|
|
||||||
if (!event.terminate())
|
if (!event.terminate())
|
||||||
ApiShared.LOGGER.error("Failed to terminate the stuck generation event!");
|
EVENT_LOGGER.error("Failed to terminate the stuck generation event!");
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
@@ -325,29 +251,31 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (unknownExceptionCount > EXCEPTION_COUNTER_TRIGGER) {
|
if (unknownExceptionCount > EXCEPTION_COUNTER_TRIGGER) {
|
||||||
try {
|
EVENT_LOGGER.error("Too many exceptions in Batching World Generator! Disabling the generator.");
|
||||||
MC.sendChatMessage("\u00A74\u00A7l\u00A7uERROR: Distant Horizons: Too many exceptions in Batching World Generator! Disabling the generator.");
|
|
||||||
} catch (Exception e) {}
|
|
||||||
ApiShared.LOGGER.error("Too many exceptions in Batching World Generator! Now disabling.");
|
|
||||||
unknownExceptionCount = 0;
|
unknownExceptionCount = 0;
|
||||||
CONFIG.client().worldGenerator().setEnableDistantGeneration(false);
|
Config.Client.WorldGenerator.enableDistantGeneration.set(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public BatchGenerationEnvironment(IWorldWrapper serverlevel, LodBuilder lodBuilder, LodDimension lodDim)
|
public BatchGenerationEnvironment(IDhServerLevel serverlevel)
|
||||||
{
|
{
|
||||||
super(serverlevel, lodBuilder, lodDim);
|
super(serverlevel);
|
||||||
ApiShared.LOGGER.info("================WORLD_GEN_STEP_INITING=============");
|
EVENT_LOGGER.info("================WORLD_GEN_STEP_INITING=============");
|
||||||
ChunkGenerator generator = ((WorldWrapper) serverlevel).getServerWorld().getChunkSource().getGenerator();
|
ChunkGenerator generator = ((ServerLevelWrapper) (serverlevel.getServerLevelWrapper())).getLevel().getChunkSource().getGenerator();
|
||||||
if (!(generator instanceof NoiseBasedChunkGenerator ||
|
if (!(generator instanceof NoiseBasedChunkGenerator ||
|
||||||
generator instanceof DebugLevelSource ||
|
generator instanceof DebugLevelSource ||
|
||||||
generator instanceof FlatLevelSource)) {
|
generator instanceof FlatLevelSource)) {
|
||||||
MC.sendChatMessage("\u00A74\u00A7l\u00A7uWARNING: Distant Horizons: Unknown Chunk Generator Detected! Distant Generation May Fail!");
|
if (generator.getClass().toString().equals("class com.terraforged.mod.chunk.TFChunkGenerator")) {
|
||||||
MC.sendChatMessage("\u00A7eIf it does crash, set Distant Generation to OFF or Generation Mode to None.");
|
EVENT_LOGGER.info("TerraForge Chunk Generator detected: [{}], Distant Generation will try its best to support it.", generator.getClass());
|
||||||
ApiShared.LOGGER.warn("Unknown Chunk Generator detected: {}", generator.getClass());
|
EVENT_LOGGER.info("If it does crash, set Distant Generation to OFF or Generation Mode to None.");
|
||||||
|
} else {
|
||||||
|
EVENT_LOGGER.warn("Unknown Chunk Generator detected: [{}], Distant Generation May Fail!", generator.getClass());
|
||||||
|
EVENT_LOGGER.warn("If it does crash, set Distant Generation to OFF or Generation Mode to None.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
params = new GlobalParameters((ServerLevel) ((WorldWrapper) serverlevel).getWorld(), lodBuilder, lodDim);
|
params = new GlobalParameters(serverlevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("resource")
|
@SuppressWarnings("resource")
|
||||||
@@ -356,23 +284,33 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
|
|||||||
CompoundTag chunkData = null;
|
CompoundTag chunkData = null;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
#if POST_MC_1_19
|
||||||
|
chunkData = level.getChunkSource().chunkMap.readChunk(chunkPos).get().orElse(null);
|
||||||
|
#else
|
||||||
chunkData = level.getChunkSource().chunkMap.readChunk(chunkPos);
|
chunkData = level.getChunkSource().chunkMap.readChunk(chunkPos);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
ApiShared.LOGGER.error("DistantHorizons: Couldn't load chunk {}", chunkPos, e);
|
LOAD_LOGGER.error("DistantHorizons: Couldn't load chunk {}", chunkPos, e);
|
||||||
}
|
}
|
||||||
if (chunkData == null)
|
if (chunkData == null)
|
||||||
{
|
{
|
||||||
return new ProtoChunk(chunkPos, UpgradeData.EMPTY, level, level.registryAccess().registryOrThrow(Registry.BIOME_REGISTRY), null);
|
return new ProtoChunk(chunkPos, UpgradeData.EMPTY
|
||||||
|
#if POST_MC_1_17_1, level #endif
|
||||||
|
#if POST_MC_1_18_1, level.registryAccess().registryOrThrow(Registry.BIOME_REGISTRY), null #endif
|
||||||
|
);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
return ChunkLoader.read(level, lightEngine, chunkPos, chunkData);
|
return ChunkLoader.read(level, lightEngine, chunkPos, chunkData);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
ApiShared.LOGGER.error("DistantHorizons: Couldn't load chunk {}", chunkPos, e);
|
LOAD_LOGGER.error("DistantHorizons: Couldn't load chunk {}", chunkPos, e);
|
||||||
return new ProtoChunk(chunkPos, UpgradeData.EMPTY, level, level.registryAccess().registryOrThrow(Registry.BIOME_REGISTRY), null);
|
return new ProtoChunk(chunkPos, UpgradeData.EMPTY
|
||||||
|
#if POST_MC_1_17_1, level #endif
|
||||||
|
#if POST_MC_1_18_1, level.registryAccess().registryOrThrow(Registry.BIOME_REGISTRY), null #endif
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -380,18 +318,17 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
|
|||||||
|
|
||||||
public void generateLodFromList(GenerationEvent e)
|
public void generateLodFromList(GenerationEvent e)
|
||||||
{
|
{
|
||||||
if (ENABLE_EVENT_LOGGING)
|
EVENT_LOGGER.debug("Lod Generate Event: " + e.minPos);
|
||||||
ApiShared.LOGGER.info("Lod Generate Event: " + e.pos);
|
|
||||||
e.pEvent.beginNano = System.nanoTime();
|
|
||||||
ArrayGridList<ChunkAccess> referencedChunks;
|
ArrayGridList<ChunkAccess> referencedChunks;
|
||||||
ArrayGridList<ChunkAccess> genChunks;
|
ArrayGridList<ChunkAccess> genChunks;
|
||||||
DistanceGenerationMode generationMode;
|
EDhApiDistantGeneratorMode generatorDetail;
|
||||||
LightedWorldGenRegion region;
|
LightedWorldGenRegion region;
|
||||||
WorldGenLevelLightEngine lightEngine;
|
WorldGenLevelLightEngine lightEngine;
|
||||||
LightGetterAdaptor adaptor;
|
LightGetterAdaptor adaptor;
|
||||||
int refRange = e.range + RANGE_TO_RANGE_EMPTY_EXTENSION;
|
int refSize = e.size+2; // +2 for the border referenced chunks
|
||||||
int refOffsetX = e.pos.x - refRange;
|
int refPosX = e.minPos.x - 1; // -1 for the border referenced chunks
|
||||||
int refOffsetZ = e.pos.z - refRange;
|
int refPosZ = e.minPos.z - 1; // -1 for the border referenced chunks
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
adaptor = new LightGetterAdaptor(params.level);
|
adaptor = new LightGetterAdaptor(params.level);
|
||||||
@@ -411,109 +348,83 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
|
|||||||
// Continue...
|
// Continue...
|
||||||
}
|
}
|
||||||
if (target == null)
|
if (target == null)
|
||||||
target = new ProtoChunk(chunkPos, UpgradeData.EMPTY, params.level,
|
target = new ProtoChunk(chunkPos, UpgradeData.EMPTY
|
||||||
params.biomes, null);
|
#if POST_MC_1_17_1, params.level #endif
|
||||||
|
#if POST_MC_1_18_1, params.biomes, null #endif
|
||||||
|
);
|
||||||
return target;
|
return target;
|
||||||
};
|
};
|
||||||
|
|
||||||
referencedChunks = new ArrayGridList<>(refRange*2+1,
|
referencedChunks = new ArrayGridList<>(refSize,
|
||||||
(x,z) -> generator.generate(x + refOffsetX,z + refOffsetZ)
|
(x,z) -> generator.generate(x + refPosX,z + refPosZ)
|
||||||
);
|
);
|
||||||
e.pEvent.emptyNano = System.nanoTime();
|
|
||||||
e.refreshTimeout();
|
e.refreshTimeout();
|
||||||
region = new LightedWorldGenRegion(params.level, lightEngine, referencedChunks,
|
region = new LightedWorldGenRegion(params.level, lightEngine, referencedChunks,
|
||||||
ChunkStatus.STRUCTURE_STARTS, refRange, e.lightMode, generator);
|
ChunkStatus.STRUCTURE_STARTS, refSize/2, e.lightMode, generator);
|
||||||
adaptor.setRegion(region);
|
adaptor.setRegion(region);
|
||||||
e.tParam.makeStructFeat(region);
|
e.tParam.makeStructFeat(region, params);
|
||||||
genChunks = new ArrayGridList<>(referencedChunks, RANGE_TO_RANGE_EMPTY_EXTENSION,
|
genChunks = new ArrayGridList<>(referencedChunks, RANGE_TO_RANGE_EMPTY_EXTENSION,
|
||||||
referencedChunks.gridSize - RANGE_TO_RANGE_EMPTY_EXTENSION);
|
referencedChunks.gridSize - RANGE_TO_RANGE_EMPTY_EXTENSION);
|
||||||
generateDirect(e, genChunks, e.target, region);
|
generateDirect(e, genChunks, e.target, region);
|
||||||
|
e.timer.nextEvent("cleanup");
|
||||||
}
|
}
|
||||||
catch (StepStructureStart.StructStartCorruptedException f)
|
catch (StepStructureStart.StructStartCorruptedException f)
|
||||||
{
|
{
|
||||||
e.tParam.markAsInvalid();
|
e.tParam.markAsInvalid();
|
||||||
return;
|
throw (RuntimeException)f.getCause();
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (e.target)
|
|
||||||
{
|
|
||||||
case Empty:
|
|
||||||
case StructureStart:
|
|
||||||
case StructureReference:
|
|
||||||
generationMode = DistanceGenerationMode.NONE;
|
|
||||||
break;
|
|
||||||
case Biomes:
|
|
||||||
generationMode = DistanceGenerationMode.BIOME_ONLY;
|
|
||||||
case Noise:
|
|
||||||
generationMode = DistanceGenerationMode.BIOME_ONLY_SIMULATE_HEIGHT;
|
|
||||||
break;
|
|
||||||
case Surface:
|
|
||||||
case Carvers:
|
|
||||||
generationMode = DistanceGenerationMode.SURFACE;
|
|
||||||
break;
|
|
||||||
case Features:
|
|
||||||
generationMode = DistanceGenerationMode.FEATURES;
|
|
||||||
break;
|
|
||||||
case Light:
|
|
||||||
case LiquidCarvers:
|
|
||||||
default:
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int oy = 0; oy < genChunks.gridSize; oy++)
|
for (int oy = 0; oy < genChunks.gridSize; oy++)
|
||||||
{
|
{
|
||||||
for (int ox = 0; ox < genChunks.gridSize; ox++)
|
for (int ox = 0; ox < genChunks.gridSize; ox++)
|
||||||
{
|
{
|
||||||
ChunkAccess target = genChunks.get(ox, oy);
|
ChunkAccess target = genChunks.get(ox, oy);
|
||||||
ChunkWrapper wrappedChunk = new ChunkWrapper(target, region);
|
ChunkWrapper wrappedChunk = new ChunkWrapper(target, region, null);
|
||||||
if (!wrappedChunk.isLightCorrect()) {
|
if (!wrappedChunk.isLightCorrect()) {
|
||||||
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 = target.getStatus() == ChunkStatus.FULL || target instanceof LevelChunk;
|
||||||
|
#if POST_MC_1_18_1
|
||||||
boolean isPartial = target.isOldNoiseGeneration();
|
boolean isPartial = target.isOldNoiseGeneration();
|
||||||
|
#endif
|
||||||
if (isFull)
|
if (isFull)
|
||||||
{
|
{
|
||||||
if (ENABLE_LOAD_EVENT_LOGGING)
|
LOAD_LOGGER.info("Detected full existing chunk at {}", target.getPos());
|
||||||
ApiShared.LOGGER.info("Detected full existing chunk at {}", target.getPos());
|
e.resultConsumer.accept(wrappedChunk);
|
||||||
params.lodBuilder.generateLodNodeFromChunk(params.lodDim, wrappedChunk,
|
|
||||||
new LodBuilderConfig(DistanceGenerationMode.FULL), true, e.genAllDetails);
|
|
||||||
}
|
}
|
||||||
|
#if POST_MC_1_18_1
|
||||||
else if (isPartial)
|
else if (isPartial)
|
||||||
{
|
{
|
||||||
if (ENABLE_LOAD_EVENT_LOGGING)
|
LOAD_LOGGER.info("Detected old existing chunk at {}", target.getPos());
|
||||||
ApiShared.LOGGER.info("Detected old existing chunk at {}", target.getPos());
|
e.resultConsumer.accept(wrappedChunk);
|
||||||
params.lodBuilder.generateLodNodeFromChunk(params.lodDim, wrappedChunk,
|
|
||||||
new LodBuilderConfig(generationMode), true, e.genAllDetails);
|
|
||||||
}
|
}
|
||||||
else if (target.getStatus() == ChunkStatus.EMPTY && generationMode == DistanceGenerationMode.NONE)
|
#endif
|
||||||
|
else if (target.getStatus() == ChunkStatus.EMPTY)
|
||||||
{
|
{
|
||||||
params.lodBuilder.generateLodNodeFromChunk(params.lodDim,wrappedChunk,
|
e.resultConsumer.accept(wrappedChunk);
|
||||||
LodBuilderConfig.getFillVoidConfig(), true, e.genAllDetails);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
params.lodBuilder.generateLodNodeFromChunk(params.lodDim, wrappedChunk,
|
e.resultConsumer.accept(wrappedChunk);
|
||||||
new LodBuilderConfig(generationMode), true, e.genAllDetails);
|
|
||||||
}
|
}
|
||||||
if (e.lightMode == LightGenerationMode.FANCY || isFull)
|
if (e.lightMode == ELightGenerationMode.FANCY || isFull)
|
||||||
{
|
{
|
||||||
lightEngine.retainData(target.getPos(), false);
|
lightEngine.retainData(target.getPos(), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
e.pEvent.endNano = System.nanoTime();
|
e.timer.complete();
|
||||||
e.refreshTimeout();
|
e.refreshTimeout();
|
||||||
if (ENABLE_PERF_LOGGING)
|
if (PREF_LOGGER.canMaybeLog())
|
||||||
{
|
{
|
||||||
e.tParam.perf.recordEvent(e.pEvent);
|
e.tParam.perf.recordEvent(e.timer);
|
||||||
ApiShared.LOGGER.info(e.tParam.perf);
|
PREF_LOGGER.infoInc("{}", e.timer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void generateDirect(GenerationEvent e, ArrayGridList<ChunkAccess> subRange, Steps step,
|
public void generateDirect(GenerationEvent e, ArrayGridList<ChunkAccess> subRange,
|
||||||
LightedWorldGenRegion region)
|
Steps step, LightedWorldGenRegion region)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -527,39 +438,41 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
|
|||||||
});
|
});
|
||||||
if (step == Steps.Empty)
|
if (step == Steps.Empty)
|
||||||
return;
|
return;
|
||||||
|
e.timer.nextEvent("structStart");
|
||||||
stepStructureStart.generateGroup(e.tParam, region, subRange);
|
stepStructureStart.generateGroup(e.tParam, region, subRange);
|
||||||
e.pEvent.structStartNano = System.nanoTime();
|
|
||||||
e.refreshTimeout();
|
e.refreshTimeout();
|
||||||
if (step == Steps.StructureStart)
|
if (step == Steps.StructureStart)
|
||||||
return;
|
return;
|
||||||
|
e.timer.nextEvent("structRef");
|
||||||
stepStructureReference.generateGroup(e.tParam, region, subRange);
|
stepStructureReference.generateGroup(e.tParam, region, subRange);
|
||||||
e.pEvent.structRefNano = System.nanoTime();
|
|
||||||
e.refreshTimeout();
|
e.refreshTimeout();
|
||||||
if (step == Steps.StructureReference)
|
if (step == Steps.StructureReference)
|
||||||
return;
|
return;
|
||||||
|
e.timer.nextEvent("biome");
|
||||||
stepBiomes.generateGroup(e.tParam, region, subRange);
|
stepBiomes.generateGroup(e.tParam, region, subRange);
|
||||||
e.pEvent.biomeNano = System.nanoTime();
|
|
||||||
e.refreshTimeout();
|
e.refreshTimeout();
|
||||||
if (step == Steps.Biomes)
|
if (step == Steps.Biomes)
|
||||||
return;
|
return;
|
||||||
|
e.timer.nextEvent("noise");
|
||||||
stepNoise.generateGroup(e.tParam, region, subRange);
|
stepNoise.generateGroup(e.tParam, region, subRange);
|
||||||
e.pEvent.noiseNano = System.nanoTime();
|
|
||||||
e.refreshTimeout();
|
e.refreshTimeout();
|
||||||
if (step == Steps.Noise)
|
if (step == Steps.Noise)
|
||||||
return;
|
return;
|
||||||
|
e.timer.nextEvent("surface");
|
||||||
stepSurface.generateGroup(e.tParam, region, subRange);
|
stepSurface.generateGroup(e.tParam, region, subRange);
|
||||||
e.pEvent.surfaceNano = System.nanoTime();
|
|
||||||
e.refreshTimeout();
|
e.refreshTimeout();
|
||||||
if (step == Steps.Surface)
|
if (step == Steps.Surface)
|
||||||
return;
|
return;
|
||||||
|
e.timer.nextEvent("carver");
|
||||||
if (step == Steps.Carvers)
|
if (step == Steps.Carvers)
|
||||||
return;
|
return;
|
||||||
|
e.timer.nextEvent("feature");
|
||||||
stepFeatures.generateGroup(e.tParam, region, subRange);
|
stepFeatures.generateGroup(e.tParam, region, subRange);
|
||||||
e.pEvent.featureNano = System.nanoTime();
|
|
||||||
e.refreshTimeout();
|
e.refreshTimeout();
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
|
e.timer.nextEvent("light");
|
||||||
switch (region.lightMode)
|
switch (region.lightMode)
|
||||||
{
|
{
|
||||||
case FANCY:
|
case FANCY:
|
||||||
@@ -570,14 +483,15 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
|
|||||||
{
|
{
|
||||||
if (p instanceof ProtoChunk)
|
if (p instanceof ProtoChunk)
|
||||||
((ProtoChunk) p).setLightCorrect(true);
|
((ProtoChunk) p).setLightCorrect(true);
|
||||||
|
#if POST_MC_1_18_1
|
||||||
if (p instanceof LevelChunk) {
|
if (p instanceof LevelChunk) {
|
||||||
((LevelChunk) p).setLightCorrect(true);
|
((LevelChunk) p).setLightCorrect(true);
|
||||||
((LevelChunk) p).setClientLightReady(true);
|
((LevelChunk) p).setClientLightReady(true);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
e.pEvent.lightNano = System.nanoTime();
|
|
||||||
e.refreshTimeout();
|
e.refreshTimeout();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -594,14 +508,30 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void stop(boolean blocking) {
|
public void stop(boolean blocking) {
|
||||||
ApiShared.LOGGER.info("Batch Chunk Generator shutting down...");
|
EVENT_LOGGER.info("Batch Chunk Generator shutting down...");
|
||||||
executors.shutdownNow();
|
executors.shutdownNow();
|
||||||
|
Iterator<GenerationEvent> iter = events.iterator();
|
||||||
|
while (iter.hasNext())
|
||||||
|
{
|
||||||
|
GenerationEvent event = iter.next();
|
||||||
|
event.future.cancel(true);
|
||||||
|
iter.remove();
|
||||||
|
}
|
||||||
if (blocking) try {
|
if (blocking) try {
|
||||||
if (!executors.awaitTermination(10, TimeUnit.SECONDS)) {
|
if (!executors.awaitTermination(10, TimeUnit.SECONDS)) {
|
||||||
ApiShared.LOGGER.error("Batch Chunk Generator shutdown failed! Ignoring child threads...");
|
EVENT_LOGGER.error("Batch Chunk Generator shutdown failed! Ignoring child threads...");
|
||||||
}
|
}
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
ApiShared.LOGGER.error("Batch Chunk Generator shutdown failed! Ignoring child threads...", e);
|
EVENT_LOGGER.error("Batch Chunk Generator shutdown failed! Ignoring child threads...", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CompletableFuture<Void> generateChunks(int minX, int minZ, int genSize, Steps targetStep, double runTimeRatio, Consumer<IChunkWrapper> resultConsumer)
|
||||||
|
{
|
||||||
|
// TODO: Check event overlap via e.tooClose()
|
||||||
|
GenerationEvent e = GenerationEvent.startEvent(new DhChunkPos(minX, minZ), genSize, this, targetStep, runTimeRatio, resultConsumer);
|
||||||
|
events.add(e);
|
||||||
|
return e.future;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+101
-68
@@ -1,111 +1,144 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
|
||||||
|
* licensed under the GNU LGPL v3 License.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2020-2022 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.lod.common.wrappers.worldGeneration;
|
package com.seibel.lod.common.wrappers.worldGeneration;
|
||||||
|
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.lang.invoke.MethodHandles;
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.CompletableFuture;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
import com.seibel.lod.common.wrappers.worldGeneration.BatchGenerationEnvironment.PrefEvent;
|
import com.seibel.lod.core.util.objects.UncheckedInterruptedException;
|
||||||
import com.seibel.lod.core.api.ApiShared;
|
import com.seibel.lod.core.config.Config;
|
||||||
import com.seibel.lod.core.enums.config.LightGenerationMode;
|
import com.seibel.lod.api.enums.config.ELightGenerationMode;
|
||||||
import com.seibel.lod.core.handlers.dependencyInjection.SingletonHandler;
|
import com.seibel.lod.core.logging.DhLoggerBuilder;
|
||||||
import com.seibel.lod.core.util.LodUtil;
|
import com.seibel.lod.core.pos.DhChunkPos;
|
||||||
import com.seibel.lod.core.wrapperInterfaces.config.ILodConfigWrapperSingleton;
|
import com.seibel.lod.core.util.objects.EventTimer;
|
||||||
|
import com.seibel.lod.core.wrapperInterfaces.chunk.IChunkWrapper;
|
||||||
import com.seibel.lod.core.wrapperInterfaces.worldGeneration.AbstractBatchGenerationEnvionmentWrapper.Steps;
|
import com.seibel.lod.core.wrapperInterfaces.worldGeneration.AbstractBatchGenerationEnvionmentWrapper.Steps;
|
||||||
|
|
||||||
import net.minecraft.world.level.ChunkPos;
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
//======================= Main Event class======================
|
//======================= Main Event class======================
|
||||||
public final class GenerationEvent
|
public final class GenerationEvent
|
||||||
{
|
{
|
||||||
static private final ILodConfigWrapperSingleton CONFIG = SingletonHandler.get(ILodConfigWrapperSingleton.class);
|
private static final Logger LOGGER = DhLoggerBuilder.getLogger(MethodHandles.lookup().lookupClass().getSimpleName());
|
||||||
|
|
||||||
private static int generationFutureDebugIDs = 0;
|
private static int generationFutureDebugIDs = 0;
|
||||||
final ThreadedParameters tParam;
|
|
||||||
final ChunkPos pos;
|
|
||||||
final int range;
|
|
||||||
final Future<?> future;
|
|
||||||
long nanotime;
|
|
||||||
final int id;
|
final int id;
|
||||||
|
final ThreadedParameters tParam;
|
||||||
|
final DhChunkPos minPos;
|
||||||
|
final int size;
|
||||||
final Steps target;
|
final Steps target;
|
||||||
final LightGenerationMode lightMode;
|
final ELightGenerationMode lightMode;
|
||||||
final PrefEvent pEvent = new PrefEvent();
|
final double runTimeRatio;
|
||||||
final boolean genAllDetails;
|
EventTimer timer = null;
|
||||||
|
long inQueueTime;
|
||||||
public GenerationEvent(ChunkPos pos, int range, BatchGenerationEnvironment generationGroup, Steps target, boolean genAllDetails)
|
long timeoutTime = -1;
|
||||||
{
|
public CompletableFuture<Void> future = null;
|
||||||
nanotime = System.nanoTime();
|
final Consumer<IChunkWrapper> resultConsumer;
|
||||||
this.pos = pos;
|
|
||||||
this.range = range;
|
public GenerationEvent(DhChunkPos minPos, int size, BatchGenerationEnvironment generationGroup,
|
||||||
id = generationFutureDebugIDs++;
|
Steps target, double runTimeRatio, Consumer<IChunkWrapper> resultConsumer) {
|
||||||
|
inQueueTime = System.nanoTime();
|
||||||
|
this.id = generationFutureDebugIDs++;
|
||||||
|
this.minPos = minPos;
|
||||||
|
this.size = size;
|
||||||
this.target = target;
|
this.target = target;
|
||||||
this.tParam = ThreadedParameters.getOrMake(generationGroup.params);
|
this.tParam = ThreadedParameters.getOrMake(generationGroup.params);
|
||||||
LightGenerationMode mode = CONFIG.client().worldGenerator().getLightGenerationMode();
|
this.lightMode = Config.Client.WorldGenerator.lightGenerationMode.get();
|
||||||
|
this.runTimeRatio = runTimeRatio;
|
||||||
this.lightMode = mode;
|
this.resultConsumer = resultConsumer;
|
||||||
this.genAllDetails = genAllDetails;
|
|
||||||
|
|
||||||
future = generationGroup.executors.submit(() ->
|
|
||||||
{
|
|
||||||
BatchGenerationEnvironment.isDistantGeneratorThread.set(true);
|
|
||||||
try {
|
|
||||||
generationGroup.generateLodFromList(this);
|
|
||||||
} finally {
|
|
||||||
BatchGenerationEnvironment.isDistantGeneratorThread.remove();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isCompleted()
|
public static GenerationEvent startEvent(DhChunkPos minPos, int size, BatchGenerationEnvironment generationGroup,
|
||||||
|
Steps target, double runTimeRatio, Consumer<IChunkWrapper> resultConsumer)
|
||||||
|
{
|
||||||
|
if (size % 2 == 0) size += 1; // size must be odd for vanilla world gen region to work
|
||||||
|
GenerationEvent event = new GenerationEvent(minPos, size, generationGroup, target, runTimeRatio, resultConsumer);
|
||||||
|
event.future = CompletableFuture.runAsync(() ->
|
||||||
|
{
|
||||||
|
long runStartTime = System.nanoTime();
|
||||||
|
event.timeoutTime = runStartTime;
|
||||||
|
event.inQueueTime = runStartTime - event.inQueueTime;
|
||||||
|
event.timer = new EventTimer("setup");
|
||||||
|
BatchGenerationEnvironment.isDistantGeneratorThread.set(true);
|
||||||
|
try {
|
||||||
|
generationGroup.generateLodFromList(event);
|
||||||
|
} finally {
|
||||||
|
BatchGenerationEnvironment.isDistantGeneratorThread.remove();
|
||||||
|
if (!Thread.interrupted() && runTimeRatio < 1.0) {
|
||||||
|
long endTime = System.nanoTime();
|
||||||
|
try {
|
||||||
|
long deltaMs = TimeUnit.NANOSECONDS.toMillis(endTime - runStartTime);
|
||||||
|
Thread.sleep((long) (deltaMs/runTimeRatio - deltaMs));
|
||||||
|
} catch (InterruptedException ignored) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, generationGroup.executors);
|
||||||
|
return event;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isComplete()
|
||||||
{
|
{
|
||||||
return future.isDone();
|
return future.isDone();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasTimeout(int duration, TimeUnit unit)
|
public boolean hasTimeout(int duration, TimeUnit unit)
|
||||||
{
|
{
|
||||||
|
if (timeoutTime == -1) return false;
|
||||||
long currentTime = System.nanoTime();
|
long currentTime = System.nanoTime();
|
||||||
long delta = currentTime - nanotime;
|
long delta = currentTime - timeoutTime;
|
||||||
return (delta > TimeUnit.NANOSECONDS.convert(duration, unit));
|
return (delta > TimeUnit.NANOSECONDS.convert(duration, unit));
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean terminate()
|
public boolean terminate()
|
||||||
{
|
{
|
||||||
ApiShared.LOGGER.info("======================DUMPING ALL THREADS FOR WORLD GEN=======================");
|
LOGGER.info("======================DUMPING ALL THREADS FOR WORLD GEN=======================");
|
||||||
BatchGenerationEnvironment.threadFactory.dumpAllThreadStacks();
|
BatchGenerationEnvironment.threadFactory.dumpAllThreadStacks();
|
||||||
future.cancel(true);
|
future.cancel(true);
|
||||||
return future.isCancelled();
|
return future.isCancelled();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void join()
|
public boolean tooClose(int minX, int minZ, int w)
|
||||||
{
|
{
|
||||||
try
|
int aMinX = minPos.x;
|
||||||
{
|
int aMinZ = minPos.z;
|
||||||
future.get();
|
int aSize = size;
|
||||||
}
|
// Account for required empty chunks in the border
|
||||||
catch (InterruptedException | ExecutionException e)
|
aSize += 1;
|
||||||
{
|
w+= 1;
|
||||||
throw new RuntimeException(e.getCause()==null? e : e.getCause());
|
// Do a AABB to AABB intersection test
|
||||||
}
|
return (aMinX + aSize >= minX &&
|
||||||
}
|
aMinX <= minX + w &&
|
||||||
|
aMinZ + aSize >= minZ &&
|
||||||
public boolean tooClose(int cx, int cz, int cr)
|
aMinZ <= minZ + w);
|
||||||
{
|
|
||||||
int distX = Math.abs(cx - pos.x);
|
|
||||||
int distZ = Math.abs(cz - pos.z);
|
|
||||||
int minRange = cr + range + 1; // Need one to account for the center
|
|
||||||
minRange += 1 + 1; // Account for required empty chunks
|
|
||||||
return distX < minRange && distZ < minRange;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void refreshTimeout()
|
public void refreshTimeout()
|
||||||
{
|
{
|
||||||
nanotime = System.nanoTime();
|
timeoutTime = System.nanoTime();
|
||||||
LodUtil.checkInterruptsUnchecked();
|
UncheckedInterruptedException.throwIfInterrupted();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString()
|
public String toString()
|
||||||
{
|
{
|
||||||
return id + ":" + range + "@" + pos + "(" + target + ")";
|
return id + ":" + size + "@" + minPos + "(" + target + ")";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+49
-17
@@ -1,10 +1,27 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
|
||||||
|
* licensed under the GNU LGPL v3 License.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2020-2022 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.lod.common.wrappers.worldGeneration;
|
package com.seibel.lod.common.wrappers.worldGeneration;
|
||||||
|
|
||||||
import com.mojang.datafixers.DataFixer;
|
import com.mojang.datafixers.DataFixer;
|
||||||
import com.seibel.lod.core.builders.lodBuilding.LodBuilder;
|
import com.seibel.lod.common.wrappers.world.ServerLevelWrapper;
|
||||||
import com.seibel.lod.core.handlers.dependencyInjection.SingletonHandler;
|
import com.seibel.lod.core.level.IDhServerLevel;
|
||||||
import com.seibel.lod.core.objects.lod.LodDimension;
|
|
||||||
|
|
||||||
import net.minecraft.core.Registry;
|
import net.minecraft.core.Registry;
|
||||||
import net.minecraft.core.RegistryAccess;
|
import net.minecraft.core.RegistryAccess;
|
||||||
@@ -14,35 +31,45 @@ 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_1
|
||||||
import net.minecraft.world.level.chunk.storage.ChunkScanAccess;
|
import net.minecraft.world.level.chunk.storage.ChunkScanAccess;
|
||||||
import net.minecraft.world.level.levelgen.DebugLevelSource;
|
#endif
|
||||||
import net.minecraft.world.level.levelgen.FlatLevelSource;
|
|
||||||
import net.minecraft.world.level.levelgen.NoiseBasedChunkGenerator;
|
|
||||||
import net.minecraft.world.level.levelgen.WorldGenSettings;
|
import net.minecraft.world.level.levelgen.WorldGenSettings;
|
||||||
|
#if PRE_MC_1_19
|
||||||
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureManager;
|
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureManager;
|
||||||
|
#else
|
||||||
|
import net.minecraft.world.level.levelgen.RandomState;
|
||||||
|
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplateManager;
|
||||||
|
#endif
|
||||||
import net.minecraft.world.level.storage.WorldData;
|
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
|
||||||
public final StructureManager structures;
|
public final StructureManager structures;
|
||||||
public final BiomeManager biomeManager;
|
#else
|
||||||
|
public final StructureTemplateManager structures;
|
||||||
|
public final RandomState randomState;
|
||||||
|
#endif
|
||||||
public final WorldGenSettings worldGenSettings;
|
public final WorldGenSettings worldGenSettings;
|
||||||
public final ThreadedLevelLightEngine lightEngine;
|
public final ThreadedLevelLightEngine lightEngine;
|
||||||
public final LodBuilder lodBuilder;
|
public final IDhServerLevel lodLevel;
|
||||||
public final LodDimension lodDim;
|
public final ServerLevel level;
|
||||||
public final Registry<Biome> biomes;
|
public final Registry<Biome> biomes;
|
||||||
public final RegistryAccess registry;
|
public final RegistryAccess registry;
|
||||||
public final long worldSeed;
|
public final long worldSeed;
|
||||||
public final ChunkScanAccess chunkScanner;
|
|
||||||
public final ServerLevel level; // TODO: Figure out a way to remove this. Maybe ClientLevel also works?
|
|
||||||
public final DataFixer fixerUpper;
|
public final DataFixer fixerUpper;
|
||||||
|
#if POST_MC_1_18_1
|
||||||
|
public final BiomeManager biomeManager;
|
||||||
|
public final ChunkScanAccess chunkScanner; // FIXME: Figure out if this is actually needed
|
||||||
|
#endif
|
||||||
|
|
||||||
public GlobalParameters(ServerLevel level, LodBuilder lodBuilder, LodDimension lodDim)
|
public GlobalParameters(IDhServerLevel lodLevel)
|
||||||
{
|
{
|
||||||
this.lodBuilder = lodBuilder;
|
this.lodLevel = lodLevel;
|
||||||
this.lodDim = lodDim;
|
|
||||||
this.level = level;
|
level = ((ServerLevelWrapper)lodLevel.getServerLevelWrapper()).getWrappedMcObject_UNSAFE();
|
||||||
lightEngine = (ThreadedLevelLightEngine) level.getLightEngine();
|
lightEngine = (ThreadedLevelLightEngine) level.getLightEngine();
|
||||||
MinecraftServer server = level.getServer();
|
MinecraftServer server = level.getServer();
|
||||||
WorldData worldData = server.getWorldData();
|
WorldData worldData = server.getWorldData();
|
||||||
@@ -50,10 +77,15 @@ public final class GlobalParameters
|
|||||||
registry = server.registryAccess();
|
registry = server.registryAccess();
|
||||||
biomes = registry.registryOrThrow(Registry.BIOME_REGISTRY);
|
biomes = registry.registryOrThrow(Registry.BIOME_REGISTRY);
|
||||||
worldSeed = worldGenSettings.seed();
|
worldSeed = worldGenSettings.seed();
|
||||||
|
#if POST_MC_1_18_1
|
||||||
biomeManager = new BiomeManager(level, BiomeManager.obfuscateSeed(worldSeed));
|
biomeManager = new BiomeManager(level, BiomeManager.obfuscateSeed(worldSeed));
|
||||||
|
chunkScanner = level.getChunkSource().chunkScanner();
|
||||||
|
#endif
|
||||||
structures = server.getStructureManager();
|
structures = server.getStructureManager();
|
||||||
generator = level.getChunkSource().getGenerator();
|
generator = level.getChunkSource().getGenerator();
|
||||||
chunkScanner = level.getChunkSource().chunkScanner();
|
|
||||||
fixerUpper = server.getFixerUpper();
|
fixerUpper = server.getFixerUpper();
|
||||||
|
#if POST_MC_1_19
|
||||||
|
randomState = level.getChunkSource().randomState();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,3 +1,22 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
|
||||||
|
* licensed under the GNU LGPL v3 License.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2020-2022 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.lod.common.wrappers.worldGeneration;
|
package com.seibel.lod.common.wrappers.worldGeneration;
|
||||||
|
|
||||||
@@ -29,6 +48,6 @@ public class Rolling
|
|||||||
|
|
||||||
public double getAverage()
|
public double getAverage()
|
||||||
{
|
{
|
||||||
return total / size;
|
return size==0 ? 0 : total / size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+35
-4
@@ -1,3 +1,22 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
|
||||||
|
* licensed under the GNU LGPL v3 License.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2020-2022 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.lod.common.wrappers.worldGeneration;
|
package com.seibel.lod.common.wrappers.worldGeneration;
|
||||||
|
|
||||||
@@ -6,14 +25,19 @@ import com.seibel.lod.common.wrappers.worldGeneration.mimicObject.WorldGenStruct
|
|||||||
|
|
||||||
import net.minecraft.server.level.ServerLevel;
|
import net.minecraft.server.level.ServerLevel;
|
||||||
import net.minecraft.world.level.WorldGenLevel;
|
import net.minecraft.world.level.WorldGenLevel;
|
||||||
|
import net.minecraft.world.level.levelgen.WorldGenSettings;
|
||||||
|
#if POST_MC_1_18_1
|
||||||
import net.minecraft.world.level.levelgen.structure.StructureCheck;
|
import net.minecraft.world.level.levelgen.structure.StructureCheck;
|
||||||
|
#endif
|
||||||
|
|
||||||
public final class ThreadedParameters
|
public final class ThreadedParameters
|
||||||
{
|
{
|
||||||
private static final ThreadLocal<ThreadedParameters> localParam = new ThreadLocal<ThreadedParameters>();
|
private static final ThreadLocal<ThreadedParameters> localParam = new ThreadLocal<ThreadedParameters>();
|
||||||
final ServerLevel level;
|
final ServerLevel level;
|
||||||
public final WorldGenStructFeatManager structFeat;
|
public WorldGenStructFeatManager structFeat = null;
|
||||||
|
#if POST_MC_1_18_1
|
||||||
public final StructureCheck structCheck;
|
public final StructureCheck structCheck;
|
||||||
|
#endif
|
||||||
boolean isValid = true;
|
boolean isValid = true;
|
||||||
public final PerfCalculator perf = new PerfCalculator();
|
public final PerfCalculator perf = new PerfCalculator();
|
||||||
|
|
||||||
@@ -35,14 +59,21 @@ public final class ThreadedParameters
|
|||||||
private ThreadedParameters(GlobalParameters param)
|
private ThreadedParameters(GlobalParameters param)
|
||||||
{
|
{
|
||||||
level = param.level;
|
level = param.level;
|
||||||
|
#if PRE_MC_1_18_1
|
||||||
|
structFeat = new WorldGenStructFeatManager(param.worldGenSettings, level);
|
||||||
|
#elif PRE_MC_1_19
|
||||||
structCheck = new StructureCheck(param.chunkScanner, param.registry, param.structures,
|
structCheck = new StructureCheck(param.chunkScanner, param.registry, param.structures,
|
||||||
param.level.dimension(), param.generator, level, param.generator.getBiomeSource(), param.worldSeed,
|
param.level.dimension(), param.generator, level, param.generator.getBiomeSource(), param.worldSeed,
|
||||||
param.fixerUpper);
|
param.fixerUpper);
|
||||||
structFeat = new WorldGenStructFeatManager(level, param.worldGenSettings, null, structCheck);
|
#else
|
||||||
|
structCheck = new StructureCheck(param.chunkScanner, param.registry, param.structures,
|
||||||
|
param.level.dimension(), param.generator, param.randomState, level, param.generator.getBiomeSource(), param.worldSeed,
|
||||||
|
param.fixerUpper);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
public void makeStructFeat(WorldGenLevel genLevel)
|
public void makeStructFeat(WorldGenLevel genLevel, GlobalParameters param)
|
||||||
{
|
{
|
||||||
structFeat.setGenLevel(genLevel);
|
structFeat = new WorldGenStructFeatManager(param.worldGenSettings, genLevel #if POST_MC_1_18_1, structCheck #endif);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+148
-193
@@ -1,25 +1,32 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
|
||||||
|
* licensed under the GNU LGPL v3 License.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2020-2022 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.lod.common.wrappers.worldGeneration.mimicObject;
|
package com.seibel.lod.common.wrappers.worldGeneration.mimicObject;
|
||||||
|
|
||||||
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.lod.core.api.ApiShared;
|
import com.seibel.lod.common.wrappers.worldGeneration.BatchGenerationEnvironment;
|
||||||
import com.seibel.lod.core.api.ClientApi;
|
|
||||||
|
import com.seibel.lod.core.logging.ConfigBasedLogger;
|
||||||
|
|
||||||
import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
|
|
||||||
import it.unimi.dsi.fastutil.longs.LongSet;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Locale;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
#if MC_VERSION_1_18_2
|
|
||||||
import net.minecraft.core.Holder;
|
|
||||||
import net.minecraft.core.RegistryAccess;
|
|
||||||
import net.minecraft.world.level.levelgen.feature.ConfiguredStructureFeature;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
import net.minecraft.core.Registry;
|
import net.minecraft.core.Registry;
|
||||||
import net.minecraft.core.SectionPos;
|
import net.minecraft.core.SectionPos;
|
||||||
@@ -27,40 +34,41 @@ 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.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
import net.minecraft.world.level.ChunkPos;
|
import net.minecraft.world.level.*;
|
||||||
import net.minecraft.world.level.Level;
|
|
||||||
import net.minecraft.world.level.LevelAccessor;
|
|
||||||
import net.minecraft.world.level.LightLayer;
|
|
||||||
import net.minecraft.world.level.WorldGenLevel;
|
|
||||||
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.biome.Biomes;
|
||||||
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.Blocks;
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
import net.minecraft.world.level.chunk.ChunkStatus;
|
import net.minecraft.world.level.chunk.*;
|
||||||
import net.minecraft.world.level.chunk.DataLayer;
|
|
||||||
import net.minecraft.world.level.chunk.LevelChunk;
|
|
||||||
import net.minecraft.world.level.chunk.LevelChunkSection;
|
|
||||||
import net.minecraft.world.level.chunk.PalettedContainer;
|
|
||||||
import net.minecraft.world.level.chunk.UpgradeData;
|
|
||||||
import net.minecraft.world.level.levelgen.Heightmap;
|
import net.minecraft.world.level.levelgen.Heightmap;
|
||||||
|
#if POST_MC_1_18_1
|
||||||
import net.minecraft.world.level.levelgen.blending.BlendingData;
|
import net.minecraft.world.level.levelgen.blending.BlendingData;
|
||||||
import net.minecraft.world.level.levelgen.feature.StructureFeature;
|
import net.minecraft.world.ticks.LevelChunkTicks;
|
||||||
import net.minecraft.world.level.levelgen.structure.StructureStart;
|
#endif
|
||||||
import net.minecraft.world.level.levelgen.structure.pieces.StructurePieceSerializationContext;
|
#if POST_MC_1_18_2
|
||||||
|
import net.minecraft.core.Holder;
|
||||||
|
#endif
|
||||||
|
|
||||||
import net.minecraft.world.level.lighting.LevelLightEngine;
|
import net.minecraft.world.level.lighting.LevelLightEngine;
|
||||||
import net.minecraft.world.level.material.Fluid;
|
import net.minecraft.world.level.material.Fluid;
|
||||||
import net.minecraft.world.ticks.LevelChunkTicks;
|
import net.minecraft.world.level.material.Fluids;
|
||||||
import org.apache.logging.log4j.Logger;
|
|
||||||
|
|
||||||
public class ChunkLoader
|
public class ChunkLoader
|
||||||
{
|
{
|
||||||
|
#if POST_MC_1_19
|
||||||
|
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_1
|
||||||
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());
|
||||||
private static final Logger LOGGER = ApiShared.LOGGER;
|
#endif
|
||||||
private static final String TAG_UPGRADE_DATA = "UpgradeData";
|
private static final String TAG_UPGRADE_DATA = "UpgradeData";
|
||||||
private static final String BLOCK_TICKS_TAG = "block_ticks";
|
private static final String BLOCK_TICKS_TAG_18 = "block_ticks";
|
||||||
private static final String FLUID_TICKS_TAG = "fluid_ticks";
|
private static final String FLUID_TICKS_TAG_18 = "fluid_ticks";
|
||||||
|
private static final String BLOCK_TICKS_TAG_PRE18 = "TileTicks";
|
||||||
|
private static final String FLUID_TICKS_TAG_PRE18 = "LiquidTicks";
|
||||||
|
private static final ConfigBasedLogger LOGGER = BatchGenerationEnvironment.LOAD_LOGGER;
|
||||||
|
|
||||||
|
#if POST_MC_1_18_1
|
||||||
private static BlendingData readBlendingData(CompoundTag chunkData)
|
private static BlendingData readBlendingData(CompoundTag chunkData)
|
||||||
{
|
{
|
||||||
BlendingData blendingData = null;
|
BlendingData blendingData = null;
|
||||||
@@ -72,36 +80,54 @@ public class ChunkLoader
|
|||||||
}
|
}
|
||||||
return blendingData;
|
return blendingData;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
private static LevelChunkSection[] readSections(LevelAccessor level, LevelLightEngine lightEngine, ChunkPos chunkPos, CompoundTag chunkData)
|
private static LevelChunkSection[] readSections(LevelAccessor level, LevelLightEngine lightEngine, ChunkPos chunkPos, CompoundTag chunkData)
|
||||||
{
|
{
|
||||||
|
#if POST_MC_1_18_1
|
||||||
Registry<Biome> biomes = level.registryAccess().registryOrThrow(Registry.BIOME_REGISTRY);
|
Registry<Biome> biomes = level.registryAccess().registryOrThrow(Registry.BIOME_REGISTRY);
|
||||||
#if MC_VERSION_1_18_1
|
#if PRE_MC_1_18_2
|
||||||
Codec<PalettedContainer<Biome>> biomeCodec = PalettedContainer.codec(
|
Codec<PalettedContainer<Biome>> biomeCodec = PalettedContainer.codec(
|
||||||
biomes, biomes.byNameCodec(), PalettedContainer.Strategy.SECTION_BIOMES, biomes.getOrThrow(Biomes.PLAINS));
|
biomes, biomes.byNameCodec(), PalettedContainer.Strategy.SECTION_BIOMES, biomes.getOrThrow(Biomes.PLAINS));
|
||||||
#elif MC_VERSION_1_18_2
|
#elif PRE_MC_1_19
|
||||||
Codec<PalettedContainer<Holder<Biome>>> biomeCodec = PalettedContainer.codec(
|
Codec<PalettedContainer<Holder<Biome>>> biomeCodec = PalettedContainer.codec(
|
||||||
biomes.asHolderIdMap(), biomes.holderByNameCodec(), PalettedContainer.Strategy.SECTION_BIOMES, biomes.getHolderOrThrow(Biomes.PLAINS));
|
biomes.asHolderIdMap(), biomes.holderByNameCodec(), PalettedContainer.Strategy.SECTION_BIOMES, biomes.getHolderOrThrow(Biomes.PLAINS));
|
||||||
|
#else
|
||||||
|
Codec<PalettedContainer<Holder<Biome>>> biomeCodec = PalettedContainer.codecRW(
|
||||||
|
biomes.asHolderIdMap(), biomes.holderByNameCodec(), PalettedContainer.Strategy.SECTION_BIOMES, biomes.getHolderOrThrow(Biomes.PLAINS));
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
int i = #if PRE_MC_1_17_1 16; #else level.getSectionsCount(); #endif
|
||||||
int i = level.getSectionsCount();
|
|
||||||
LevelChunkSection[] chunkSections = new LevelChunkSection[i];
|
LevelChunkSection[] chunkSections = new LevelChunkSection[i];
|
||||||
|
|
||||||
boolean isLightOn = chunkData.getBoolean("isLightOn");
|
boolean isLightOn = chunkData.getBoolean("isLightOn");
|
||||||
boolean hasSkyLight = level.dimensionType().hasSkyLight();
|
boolean hasSkyLight = level.dimensionType().hasSkyLight();
|
||||||
ListTag tagSections = chunkData.getList("sections", 10);
|
ListTag tagSections = chunkData.getList("Sections", 10);
|
||||||
|
if (tagSections.isEmpty()) tagSections = chunkData.getList("sections", 10);
|
||||||
|
|
||||||
for (int j = 0; j < tagSections.size(); ++j)
|
for (int j = 0; j < tagSections.size(); ++j)
|
||||||
{
|
{
|
||||||
CompoundTag tagSection = tagSections.getCompound(j);
|
CompoundTag tagSection = tagSections.getCompound(j);
|
||||||
byte sectionYPos = tagSection.getByte("Y");
|
int sectionYPos = tagSection.getByte("Y");
|
||||||
|
|
||||||
|
#if PRE_MC_1_18_1
|
||||||
|
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);
|
int sectionId = level.getSectionIndexFromSectionY(sectionYPos);
|
||||||
if (sectionId >= 0 && sectionId < chunkSections.length)
|
if (sectionId >= 0 && sectionId < chunkSections.length)
|
||||||
{
|
{
|
||||||
PalettedContainer<BlockState> blockStateContainer;
|
PalettedContainer<BlockState> blockStateContainer;
|
||||||
#if MC_VERSION_1_18_1
|
#if PRE_MC_1_18_2
|
||||||
PalettedContainer<Biome> biomeContainer;
|
PalettedContainer<Biome> biomeContainer;
|
||||||
#elif MC_VERSION_1_18_2
|
#else
|
||||||
PalettedContainer<Holder<Biome>> biomeContainer;
|
PalettedContainer<Holder<Biome>> biomeContainer;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -109,27 +135,26 @@ public class ChunkLoader
|
|||||||
? BLOCK_STATE_CODEC.parse(NbtOps.INSTANCE, tagSection.getCompound("block_states")).promotePartial(string -> logErrors(chunkPos, sectionYPos, string)).getOrThrow(false, LOGGER::error)
|
? 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);
|
: new PalettedContainer<BlockState>(Block.BLOCK_STATE_REGISTRY, Blocks.AIR.defaultBlockState(), PalettedContainer.Strategy.SECTION_STATES);
|
||||||
|
|
||||||
#if MC_VERSION_1_18_1
|
#if PRE_MC_1_18_2
|
||||||
biomeContainer = tagSection.contains("biomes", 10)
|
biomeContainer = tagSection.contains("biomes", 10)
|
||||||
? biomeCodec.parse(NbtOps.INSTANCE, tagSection.getCompound("biomes")).promotePartial(string -> logErrors(chunkPos, sectionYPos, string)).getOrThrow(false, LOGGER::error)
|
? 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);
|
: new PalettedContainer<Biome>(biomes, biomes.getOrThrow(Biomes.PLAINS), PalettedContainer.Strategy.SECTION_BIOMES);
|
||||||
#elif MC_VERSION_1_18_2
|
#else
|
||||||
biomeContainer = tagSection.contains("biomes", 10)
|
biomeContainer = tagSection.contains("biomes", 10)
|
||||||
? biomeCodec.parse(NbtOps.INSTANCE, tagSection.getCompound("biomes")).promotePartial(string -> logErrors(chunkPos, i, (String) string)).getOrThrow(false, LOGGER::error)
|
? 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);
|
: new PalettedContainer<Holder<Biome>>(biomes.asHolderIdMap(), biomes.getHolderOrThrow(Biomes.PLAINS), PalettedContainer.Strategy.SECTION_BIOMES);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
chunkSections[sectionId] = new LevelChunkSection(sectionYPos, blockStateContainer, biomeContainer);
|
chunkSections[sectionId] = new LevelChunkSection(sectionYPos, blockStateContainer, biomeContainer);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!isLightOn)
|
if (!isLightOn) continue;
|
||||||
continue;
|
|
||||||
|
|
||||||
if (tagSection.contains("BlockLight", 7))
|
if (tagSection.contains("BlockLight", 7))
|
||||||
lightEngine.queueSectionData(LightLayer.BLOCK, SectionPos.of(chunkPos, sectionYPos), new DataLayer(tagSection.getByteArray("BlockLight")), true);
|
lightEngine.queueSectionData(LightLayer.BLOCK, SectionPos.of(chunkPos, sectionYPos),
|
||||||
|
new DataLayer(tagSection.getByteArray("BlockLight")), true);
|
||||||
if (hasSkyLight && tagSection.contains("SkyLight", 7))
|
if (hasSkyLight && tagSection.contains("SkyLight", 7))
|
||||||
lightEngine.queueSectionData(LightLayer.SKY, SectionPos.of(chunkPos, sectionYPos), new DataLayer(tagSection.getByteArray("SkyLight")), true);
|
lightEngine.queueSectionData(LightLayer.SKY, SectionPos.of(chunkPos, sectionYPos),
|
||||||
|
new DataLayer(tagSection.getByteArray("SkyLight")), true);
|
||||||
}
|
}
|
||||||
return chunkSections;
|
return chunkSections;
|
||||||
}
|
}
|
||||||
@@ -146,115 +171,6 @@ public class ChunkLoader
|
|||||||
Heightmap.primeHeightmaps(chunk, ChunkStatus.FULL.heightmapsAfter());
|
Heightmap.primeHeightmaps(chunk, ChunkStatus.FULL.heightmapsAfter());
|
||||||
}
|
}
|
||||||
|
|
||||||
#if MC_VERSION_1_18_1
|
|
||||||
private static Map<StructureFeature<?>, StructureStart<?>> unpackStructureStart(StructurePieceSerializationContext structurePieceSerializationContext, CompoundTag compoundTag, long l)
|
|
||||||
{
|
|
||||||
HashMap<StructureFeature<?>, StructureStart<?>> map = Maps.newHashMap();
|
|
||||||
CompoundTag compoundTag2 = compoundTag.getCompound("starts");
|
|
||||||
for (String string : compoundTag2.getAllKeys())
|
|
||||||
{
|
|
||||||
String string2 = string.toLowerCase(Locale.ROOT);
|
|
||||||
StructureFeature<?> structureFeature = StructureFeature.STRUCTURES_REGISTRY.get(string2);
|
|
||||||
if (structureFeature == null)
|
|
||||||
{
|
|
||||||
LOGGER.error("Unknown structure start: {}", (Object) string2);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
StructureStart<?> structureStart = StructureFeature.loadStaticStart(structurePieceSerializationContext, compoundTag2.getCompound(string), l);
|
|
||||||
if (structureStart == null)
|
|
||||||
continue;
|
|
||||||
map.put(structureFeature, structureStart);
|
|
||||||
}
|
|
||||||
return map;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Map<StructureFeature<?>, LongSet> unpackStructureReferences(ChunkPos chunkPos, CompoundTag compoundTag)
|
|
||||||
{
|
|
||||||
HashMap<StructureFeature<?>, LongSet> map = Maps.newHashMap();
|
|
||||||
CompoundTag compoundTag2 = compoundTag.getCompound("References");
|
|
||||||
for (String string : compoundTag2.getAllKeys())
|
|
||||||
{
|
|
||||||
String string2 = string.toLowerCase(Locale.ROOT);
|
|
||||||
StructureFeature<?> structureFeature = StructureFeature.STRUCTURES_REGISTRY.get(string2);
|
|
||||||
if (structureFeature == null)
|
|
||||||
{
|
|
||||||
LOGGER.warn("Found reference to unknown structure '{}' in chunk {}, discarding", (Object) string2, (Object) chunkPos);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
map.put(structureFeature, new LongOpenHashSet(Arrays.stream(compoundTag2.getLongArray(string)).filter(l ->
|
|
||||||
{
|
|
||||||
ChunkPos chunkPos2 = new ChunkPos(l);
|
|
||||||
if (chunkPos2.getChessboardDistance(chunkPos) > 8)
|
|
||||||
{
|
|
||||||
LOGGER.warn("Found invalid structure reference [ {} @ {} ] for chunk {}.", (Object) string2, (Object) chunkPos2, (Object) chunkPos);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}).toArray()));
|
|
||||||
}
|
|
||||||
return map;
|
|
||||||
}
|
|
||||||
#elif MC_VERSION_1_18_2
|
|
||||||
private static Map<ConfiguredStructureFeature<?, ?>, StructureStart> unpackStructureStart(StructurePieceSerializationContext structurePieceSerializationContext, CompoundTag compoundTag, long l) {
|
|
||||||
Map<ConfiguredStructureFeature<?, ?>, StructureStart> map = Maps.newHashMap();
|
|
||||||
Registry<ConfiguredStructureFeature<?, ?>> structStartRegistry = structurePieceSerializationContext.registryAccess().registryOrThrow(Registry.CONFIGURED_STRUCTURE_FEATURE_REGISTRY);
|
|
||||||
CompoundTag compoundTag2 = compoundTag.getCompound("starts");
|
|
||||||
for (String string : compoundTag2.getAllKeys()) {
|
|
||||||
ResourceLocation resourceLocation = ResourceLocation.tryParse(string);
|
|
||||||
ConfiguredStructureFeature<?, ?> structureFeature = structStartRegistry.get(resourceLocation);
|
|
||||||
// String string2 = string.toLowerCase(Locale.ROOT);
|
|
||||||
// ConfiguredStructureFeature<?, ?> structureFeature = StructureFeature.STRUCTURES_REGISTRY.get(string2);
|
|
||||||
if (structureFeature == null) {
|
|
||||||
LOGGER.error("Unknown structure start: {}", resourceLocation);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
StructureStart structureStart = StructureFeature.loadStaticStart(structurePieceSerializationContext, compoundTag2.getCompound(string), l);
|
|
||||||
if (structureStart == null)
|
|
||||||
continue;
|
|
||||||
map.put(structureFeature, structureStart);
|
|
||||||
}
|
|
||||||
return map;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Map<ConfiguredStructureFeature<?, ?>, LongSet> unpackStructureReferences(RegistryAccess registryAccess, ChunkPos chunkPos, CompoundTag compoundTag)
|
|
||||||
{
|
|
||||||
Map<ConfiguredStructureFeature<?, ?>, LongSet> map = Maps.newHashMap();
|
|
||||||
Registry<ConfiguredStructureFeature<?, ?>> structRegistry = registryAccess.registryOrThrow(Registry.CONFIGURED_STRUCTURE_FEATURE_REGISTRY);
|
|
||||||
CompoundTag compoundTag2 = compoundTag.getCompound("References");
|
|
||||||
for (String string : compoundTag2.getAllKeys())
|
|
||||||
{
|
|
||||||
ResourceLocation resourceLocation = ResourceLocation.tryParse(string);
|
|
||||||
ConfiguredStructureFeature<?, ?> structureFeature = structRegistry.get(resourceLocation);
|
|
||||||
// String string2 = string.toLowerCase(Locale.ROOT);
|
|
||||||
// ConfiguredStructureFeature<?, ?> structureFeature = StructureFeature.STRUCTURES_REGISTRY.get(string2);
|
|
||||||
if (structureFeature == null)
|
|
||||||
{
|
|
||||||
LOGGER.warn("Found reference to unknown structure '{}' in chunk {}, discarding", resourceLocation, chunkPos);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
map.put(structureFeature, new LongOpenHashSet(Arrays.stream(compoundTag2.getLongArray(string)).filter(l ->
|
|
||||||
{
|
|
||||||
ChunkPos chunkPos2 = new ChunkPos(l);
|
|
||||||
if (chunkPos2.getChessboardDistance(chunkPos) > 8)
|
|
||||||
{
|
|
||||||
LOGGER.warn("Found invalid structure reference [ {} @ {} ] for chunk {}.", resourceLocation, chunkPos2, chunkPos);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}).toArray()));
|
|
||||||
}
|
|
||||||
return map;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
private static void readStructures(WorldGenLevel level, LevelChunk chunk, CompoundTag chunkData)
|
|
||||||
{
|
|
||||||
CompoundTag tagStructures = chunkData.getCompound("structures");
|
|
||||||
chunk.setAllStarts(
|
|
||||||
unpackStructureStart(StructurePieceSerializationContext.fromLevel(level.getLevel()), tagStructures, level.getSeed()));
|
|
||||||
chunk.setAllReferences(unpackStructureReferences(#if MC_VERSION_1_18_2 level.registryAccess() ,#endif chunk.getPos(), tagStructures));
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void readPostPocessings(LevelChunk chunk, CompoundTag chunkData)
|
private static void readPostPocessings(LevelChunk chunk, CompoundTag chunkData)
|
||||||
{
|
{
|
||||||
ListTag tagPostProcessings = chunkData.getList("PostProcessing", 9);
|
ListTag tagPostProcessings = chunkData.getList("PostProcessing", 9);
|
||||||
@@ -268,49 +184,88 @@ public class ChunkLoader
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ChunkStatus.ChunkType readChunkType(CompoundTag compoundTag)
|
public static ChunkStatus.ChunkType readChunkType(CompoundTag tagLevel)
|
||||||
{
|
{
|
||||||
return ChunkStatus.byName(compoundTag.getString("Status")).getChunkType();
|
ChunkStatus chunkStatus = ChunkStatus.byName(tagLevel.getString("Status"));
|
||||||
|
if (chunkStatus != null) {
|
||||||
|
return chunkStatus.getChunkType();
|
||||||
|
}
|
||||||
|
return ChunkStatus.ChunkType.PROTOCHUNK;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static LevelChunk read(WorldGenLevel level, LevelLightEngine lightEngine, ChunkPos chunkPos, CompoundTag chunkData)
|
public static LevelChunk read(WorldGenLevel level, LevelLightEngine lightEngine, ChunkPos chunkPos, CompoundTag chunkData)
|
||||||
{
|
{
|
||||||
|
#if PRE_MC_1_18_1
|
||||||
ChunkPos actualPos = new ChunkPos(chunkData.getInt("xPos"), chunkData.getInt("zPos"));
|
CompoundTag tagLevel = chunkData.getCompound("Level");
|
||||||
if (!Objects.equals(chunkPos, actualPos))
|
#else
|
||||||
{
|
CompoundTag tagLevel = chunkData;
|
||||||
LOGGER.error("Distant Horizons: Chunk file at {} is in the wrong location; Ignoring. (Expected {}, got {})", (Object) chunkPos, (Object) chunkPos, (Object) actualPos);
|
#endif
|
||||||
|
|
||||||
|
ChunkPos actualPos = new ChunkPos(tagLevel.getInt("xPos"), tagLevel.getInt("zPos"));
|
||||||
|
if (!Objects.equals(chunkPos, actualPos)) {
|
||||||
|
LOGGER.error("Chunk file at {} is in the wrong location; Ignoring. (Expected {}, got {})", chunkPos, chunkPos, actualPos);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
ChunkStatus.ChunkType chunkType = readChunkType(chunkData);
|
ChunkStatus.ChunkType chunkType = readChunkType(tagLevel);
|
||||||
BlendingData blendingData = readBlendingData(chunkData);
|
#if PRE_MC_1_18_1
|
||||||
|
if (chunkType != ChunkStatus.ChunkType.LEVELCHUNK)
|
||||||
|
return null;
|
||||||
|
#else
|
||||||
|
BlendingData blendingData = readBlendingData(tagLevel);
|
||||||
|
#if PRE_MC_1_19
|
||||||
if (chunkType == ChunkStatus.ChunkType.PROTOCHUNK && (blendingData == null || !blendingData.oldNoise()))
|
if (chunkType == ChunkStatus.ChunkType.PROTOCHUNK && (blendingData == null || !blendingData.oldNoise()))
|
||||||
return null;
|
return null;
|
||||||
|
#else
|
||||||
// Prepare the light engine
|
if (chunkType == ChunkStatus.ChunkType.PROTOCHUNK && (blendingData == null || level.getChunk(chunkPos.getMiddleBlockX(),chunkPos.getMiddleBlockZ()).isOldNoiseGeneration()))
|
||||||
boolean isLightOn = chunkData.getBoolean("isLightOn");
|
return null;
|
||||||
if (isLightOn)
|
#endif
|
||||||
level.getLightEngine().retainData(chunkPos, true);
|
#endif
|
||||||
|
|
||||||
// Read params for making the LevelChunk
|
long inhabitedTime = tagLevel.getLong("InhabitedTime");
|
||||||
UpgradeData upgradeData = chunkData.contains(TAG_UPGRADE_DATA, 10)
|
|
||||||
? new UpgradeData(chunkData.getCompound(TAG_UPGRADE_DATA), level)
|
//================== Read params for making the LevelChunk ==================
|
||||||
|
UpgradeData upgradeData = tagLevel.contains(TAG_UPGRADE_DATA, 10)
|
||||||
|
? new UpgradeData(tagLevel.getCompound(TAG_UPGRADE_DATA)#if POST_MC_1_17_1, level #endif)
|
||||||
: UpgradeData.EMPTY;
|
: UpgradeData.EMPTY;
|
||||||
LevelChunkTicks<Block> blockTicks = LevelChunkTicks.load(chunkData.getList(BLOCK_TICKS_TAG, 10),
|
|
||||||
|
boolean isLightOn = tagLevel.getBoolean("isLightOn");
|
||||||
|
if (isLightOn) lightEngine.retainData(chunkPos, true);
|
||||||
|
#if PRE_MC_1_18_1
|
||||||
|
ChunkBiomeContainer chunkBiomeContainer = new ChunkBiomeContainer(
|
||||||
|
level.getLevel().registryAccess().registryOrThrow(Registry.BIOME_REGISTRY)#if POST_MC_1_17_1, level #endif,
|
||||||
|
chunkPos, level.getLevel().getChunkSource().getGenerator().getBiomeSource(),
|
||||||
|
tagLevel.contains("Biomes", 11) ? tagLevel.getIntArray("Biomes") : null);
|
||||||
|
|
||||||
|
TickList<Block> blockTicks = tagLevel.contains(BLOCK_TICKS_TAG_PRE18, 9)
|
||||||
|
? ChunkTickList.create(tagLevel.getList(BLOCK_TICKS_TAG_PRE18, 10), Registry.BLOCK::getKey, Registry.BLOCK::get)
|
||||||
|
: new ProtoTickList<Block>(block -> (block == null || block.defaultBlockState().isAir()), chunkPos,
|
||||||
|
tagLevel.getList("ToBeTicked", 9)#if POST_MC_1_17_1, level #endif);
|
||||||
|
|
||||||
|
TickList<Fluid> fluidTicks = tagLevel.contains(FLUID_TICKS_TAG_PRE18, 9)
|
||||||
|
? ChunkTickList.create(tagLevel.getList(FLUID_TICKS_TAG_PRE18, 10), Registry.FLUID::getKey, Registry.FLUID::get)
|
||||||
|
: new ProtoTickList<Fluid>(fluid -> (fluid == null || fluid == Fluids.EMPTY), chunkPos,
|
||||||
|
tagLevel.getList("LiquidsToBeTicked", 9)#if POST_MC_1_17_1, level #endif);
|
||||||
|
#else
|
||||||
|
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(chunkData.getList(FLUID_TICKS_TAG, 10),
|
LevelChunkTicks<Fluid> fluidTicks = LevelChunkTicks.load(tagLevel.getList(FLUID_TICKS_TAG_18, 10),
|
||||||
string -> Registry.FLUID.getOptional(ResourceLocation.tryParse(string)), chunkPos);
|
string -> Registry.FLUID.getOptional(ResourceLocation.tryParse(string)), chunkPos);
|
||||||
long inhabitedTime = chunkData.getLong("InhabitedTime");
|
#endif
|
||||||
LevelChunkSection[] chunkSections = readSections(level, lightEngine, actualPos, chunkData);
|
|
||||||
|
LevelChunkSection[] levelChunkSections = readSections(level, lightEngine, chunkPos, tagLevel);
|
||||||
// Make chunk
|
|
||||||
LevelChunk chunk = new LevelChunk((Level) level, chunkPos, upgradeData, blockTicks, fluidTicks, inhabitedTime, chunkSections, null, blendingData);
|
// ====================== Make the chunk =========================
|
||||||
|
#if PRE_MC_1_18_1
|
||||||
|
LevelChunk chunk = new LevelChunk((Level) level.getLevel(), chunkPos, chunkBiomeContainer, upgradeData, blockTicks,
|
||||||
|
fluidTicks, inhabitedTime, levelChunkSections, null);
|
||||||
|
#else
|
||||||
|
LevelChunk chunk = new LevelChunk((Level) level, chunkPos, upgradeData, blockTicks,
|
||||||
|
fluidTicks, inhabitedTime, levelChunkSections, null, blendingData);
|
||||||
|
#endif
|
||||||
// Set some states after object creation
|
// Set some states after object creation
|
||||||
chunk.setLightCorrect(isLightOn);
|
chunk.setLightCorrect(isLightOn);
|
||||||
readHeightmaps(chunk, chunkData);
|
readHeightmaps(chunk, chunkData);
|
||||||
readStructures(level, chunk, chunkData);
|
|
||||||
readPostPocessings(chunk, chunkData);
|
readPostPocessings(chunk, chunkData);
|
||||||
return chunk;
|
return chunk;
|
||||||
}
|
}
|
||||||
|
|||||||
+26
-2
@@ -1,10 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
|
||||||
|
* licensed under the GNU LGPL v3 License.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2020-2022 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.lod.common.wrappers.worldGeneration.mimicObject;
|
package com.seibel.lod.common.wrappers.worldGeneration.mimicObject;
|
||||||
|
|
||||||
import com.seibel.lod.core.handlers.dependencyInjection.ModAccessorHandler;
|
import com.seibel.lod.core.dependencyInjection.ModAccessorInjector;
|
||||||
import com.seibel.lod.core.wrapperInterfaces.modAccessor.IStarlightAccessor;
|
import com.seibel.lod.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.LevelHeightAccessor;
|
import net.minecraft.world.level.LevelHeightAccessor;
|
||||||
|
#endif
|
||||||
import net.minecraft.world.level.chunk.ChunkStatus;
|
import net.minecraft.world.level.chunk.ChunkStatus;
|
||||||
import net.minecraft.world.level.chunk.LightChunkGetter;
|
import net.minecraft.world.level.chunk.LightChunkGetter;
|
||||||
|
|
||||||
@@ -15,7 +36,7 @@ public class LightGetterAdaptor implements LightChunkGetter {
|
|||||||
|
|
||||||
public LightGetterAdaptor(BlockGetter heightAccessor) {
|
public LightGetterAdaptor(BlockGetter heightAccessor) {
|
||||||
this.heightGetter = heightAccessor;
|
this.heightGetter = heightAccessor;
|
||||||
shouldReturnNull = ModAccessorHandler.get(IStarlightAccessor.class) != null;
|
shouldReturnNull = ModAccessorInjector.INSTANCE.get(IStarlightAccessor.class) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setRegion(LightedWorldGenRegion region) {
|
public void setRegion(LightedWorldGenRegion region) {
|
||||||
@@ -34,7 +55,10 @@ public class LightGetterAdaptor implements LightChunkGetter {
|
|||||||
public BlockGetter getLevel() {
|
public BlockGetter getLevel() {
|
||||||
return shouldReturnNull ? null : (genRegion != null ? genRegion : heightGetter);
|
return shouldReturnNull ? null : (genRegion != null ? genRegion : heightGetter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if POST_MC_1_17_1
|
||||||
public LevelHeightAccessor getLevelHeightAccessor() {
|
public LevelHeightAccessor getLevelHeightAccessor() {
|
||||||
return heightGetter;
|
return heightGetter;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
+85
-34
@@ -1,20 +1,38 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
|
||||||
|
* licensed under the GNU LGPL v3 License.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2020-2022 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.lod.common.wrappers.worldGeneration.mimicObject;
|
package com.seibel.lod.common.wrappers.worldGeneration.mimicObject;
|
||||||
|
|
||||||
|
import java.lang.invoke.MethodHandles;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import com.seibel.lod.core.api.ApiShared;
|
import com.seibel.lod.core.logging.DhLoggerBuilder;
|
||||||
|
import net.minecraft.world.level.block.EntityBlock;
|
||||||
|
import net.minecraft.world.level.block.SpawnerBlock;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import com.seibel.lod.common.wrappers.worldGeneration.BatchGenerationEnvironment.EmptyChunkGenerator;
|
import com.seibel.lod.common.wrappers.worldGeneration.BatchGenerationEnvironment.EmptyChunkGenerator;
|
||||||
import com.seibel.lod.core.api.ClientApi;
|
import com.seibel.lod.api.enums.config.ELightGenerationMode;
|
||||||
import com.seibel.lod.core.enums.config.LightGenerationMode;
|
|
||||||
|
|
||||||
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
|
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
|
||||||
import it.unimi.dsi.fastutil.objects.Object2ObjectArrayMap;
|
|
||||||
import net.minecraft.Util;
|
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.color.block.BlockTintCache;
|
|
||||||
import net.minecraft.client.renderer.BiomeColors;
|
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.core.Cursor3D;
|
import net.minecraft.core.Cursor3D;
|
||||||
import net.minecraft.core.SectionPos;
|
import net.minecraft.core.SectionPos;
|
||||||
@@ -24,9 +42,10 @@ 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
|
||||||
import net.minecraft.world.level.LevelHeightAccessor;
|
import net.minecraft.world.level.LevelHeightAccessor;
|
||||||
|
#endif
|
||||||
import net.minecraft.world.level.LightLayer;
|
import net.minecraft.world.level.LightLayer;
|
||||||
import net.minecraft.world.level.StructureFeatureManager;
|
|
||||||
import net.minecraft.world.level.biome.Biome;
|
import net.minecraft.world.level.biome.Biome;
|
||||||
import net.minecraft.world.level.block.Blocks;
|
import net.minecraft.world.level.block.Blocks;
|
||||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||||
@@ -36,24 +55,47 @@ 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.levelgen.Heightmap;
|
import net.minecraft.world.level.levelgen.Heightmap;
|
||||||
import net.minecraft.world.level.levelgen.feature.StructureFeature;
|
|
||||||
import net.minecraft.world.level.levelgen.structure.StructureStart;
|
|
||||||
import net.minecraft.world.level.lighting.LevelLightEngine;
|
import net.minecraft.world.level.lighting.LevelLightEngine;
|
||||||
|
|
||||||
public class LightedWorldGenRegion extends WorldGenRegion {
|
public class LightedWorldGenRegion extends WorldGenRegion
|
||||||
|
{
|
||||||
|
private static final Logger LOGGER = DhLoggerBuilder.getLogger(MethodHandles.lookup().lookupClass().getSimpleName());
|
||||||
|
|
||||||
public final WorldGenLevelLightEngine light;
|
public final WorldGenLevelLightEngine light;
|
||||||
public final LightGenerationMode lightMode;
|
public final ELightGenerationMode lightMode;
|
||||||
public final EmptyChunkGenerator generator;
|
public final EmptyChunkGenerator 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>();
|
Long2ObjectOpenHashMap<ChunkAccess> chunkMap = new Long2ObjectOpenHashMap<ChunkAccess>();
|
||||||
|
|
||||||
|
#if PRE_MC_1_18_1
|
||||||
|
private ChunkPos overrideCenterPos = null;
|
||||||
|
|
||||||
|
public void setOverrideCenter(ChunkPos pos) {overrideCenterPos = pos;}
|
||||||
|
#if PRE_MC_1_17_1
|
||||||
|
@Override
|
||||||
|
public int getCenterX() {
|
||||||
|
return overrideCenterPos==null ? super.getCenterX() : overrideCenterPos.x;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public int getCenterZ() {
|
||||||
|
return overrideCenterPos==null ? super.getCenterX() : overrideCenterPos.z;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
@Override
|
||||||
|
public ChunkPos getCenter() {
|
||||||
|
return overrideCenterPos==null ? super.getCenter() : overrideCenterPos;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
public LightedWorldGenRegion(ServerLevel serverLevel, WorldGenLevelLightEngine lightEngine,
|
public LightedWorldGenRegion(ServerLevel serverLevel, WorldGenLevelLightEngine lightEngine,
|
||||||
List<ChunkAccess> list, ChunkStatus chunkStatus, int i,
|
List<ChunkAccess> list, ChunkStatus chunkStatus, int i,
|
||||||
LightGenerationMode lightMode, EmptyChunkGenerator generator) {
|
ELightGenerationMode lightMode, EmptyChunkGenerator generator)
|
||||||
super(serverLevel, list, chunkStatus, i);
|
{
|
||||||
|
super(serverLevel, list #if POST_MC_1_17_1, chunkStatus, i #endif);
|
||||||
this.lightMode = lightMode;
|
this.lightMode = lightMode;
|
||||||
this.firstPos = list.get(0).getPos();
|
this.firstPos = list.get(0).getPos();
|
||||||
this.generator = generator;
|
this.generator = generator;
|
||||||
@@ -61,17 +103,13 @@ public class LightedWorldGenRegion extends WorldGenRegion {
|
|||||||
writeRadius = i;
|
writeRadius = i;
|
||||||
cache = list;
|
cache = list;
|
||||||
size = Mth.floor(Math.sqrt(list.size()));
|
size = Mth.floor(Math.sqrt(list.size()));
|
||||||
|
|
||||||
this.tintCaches = Util.make(new Object2ObjectArrayMap(3), object2ObjectArrayMap -> {
|
|
||||||
object2ObjectArrayMap.put(BiomeColors.GRASS_COLOR_RESOLVER, new BlockTintCache((pos) -> {return calculateBlockTint(pos, BiomeColors.GRASS_COLOR_RESOLVER);}));
|
|
||||||
object2ObjectArrayMap.put(BiomeColors.FOLIAGE_COLOR_RESOLVER, new BlockTintCache((pos) -> {return calculateBlockTint(pos, BiomeColors.FOLIAGE_COLOR_RESOLVER);}));
|
|
||||||
object2ObjectArrayMap.put(BiomeColors.WATER_COLOR_RESOLVER, new BlockTintCache((pos) -> {return calculateBlockTint(pos, BiomeColors.WATER_COLOR_RESOLVER);}));
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if POST_MC_1_17_1
|
||||||
// Bypass BCLib mixin overrides.
|
// Bypass BCLib mixin overrides.
|
||||||
@Override
|
@Override
|
||||||
public boolean ensureCanWrite(BlockPos blockPos) {
|
public boolean ensureCanWrite(BlockPos blockPos)
|
||||||
|
{
|
||||||
int i = SectionPos.blockToSectionCoord(blockPos.getX());
|
int i = SectionPos.blockToSectionCoord(blockPos.getX());
|
||||||
int j = SectionPos.blockToSectionCoord(blockPos.getZ());
|
int j = SectionPos.blockToSectionCoord(blockPos.getZ());
|
||||||
ChunkPos chunkPos = this.getCenter();
|
ChunkPos chunkPos = this.getCenter();
|
||||||
@@ -81,14 +119,17 @@ public class LightedWorldGenRegion extends WorldGenRegion {
|
|||||||
if (k > this.writeRadius || l > this.writeRadius) {
|
if (k > this.writeRadius || l > this.writeRadius) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
#if POST_MC_1_18_1
|
||||||
if (center.isUpgrading()) {
|
if (center.isUpgrading()) {
|
||||||
LevelHeightAccessor levelHeightAccessor = center.getHeightAccessorForGeneration();
|
LevelHeightAccessor levelHeightAccessor = center.getHeightAccessorForGeneration();
|
||||||
if (blockPos.getY() < levelHeightAccessor.getMinBuildHeight() || blockPos.getY() >= levelHeightAccessor.getMaxBuildHeight()) {
|
if (blockPos.getY() < levelHeightAccessor.getMinBuildHeight() || blockPos.getY() >= levelHeightAccessor.getMaxBuildHeight()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// TODO Check this
|
// TODO Check this
|
||||||
// @Override
|
// @Override
|
||||||
@@ -124,7 +165,18 @@ public class LightedWorldGenRegion extends WorldGenRegion {
|
|||||||
// Skip BlockEntity stuff. It aren't really needed
|
// Skip BlockEntity stuff. It aren't really needed
|
||||||
@Override
|
@Override
|
||||||
public BlockEntity getBlockEntity(BlockPos blockPos) {
|
public BlockEntity getBlockEntity(BlockPos blockPos) {
|
||||||
return null;
|
BlockState blockState = this.getBlockState(blockPos);
|
||||||
|
|
||||||
|
// This is a bypass for the spawner block since MC complains about not having it
|
||||||
|
#if POST_MC_1_17_1
|
||||||
|
if (blockState.getBlock() instanceof SpawnerBlock) {
|
||||||
|
return ((EntityBlock) blockState.getBlock()).newBlockEntity(blockPos, blockState);
|
||||||
|
} else return null;
|
||||||
|
#else
|
||||||
|
if (blockState.getBlock() instanceof SpawnerBlock) {
|
||||||
|
return ((EntityBlock) blockState.getBlock()).newBlockEntity(this);
|
||||||
|
} else return null;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Skip BlockEntity stuff. It aren't really needed
|
// Skip BlockEntity stuff. It aren't really needed
|
||||||
@@ -173,7 +225,7 @@ public class LightedWorldGenRegion extends WorldGenRegion {
|
|||||||
public ChunkAccess getChunk(int i, int j, ChunkStatus chunkStatus, boolean bl) {
|
public ChunkAccess getChunk(int i, int j, ChunkStatus chunkStatus, boolean bl) {
|
||||||
ChunkAccess chunk = getChunkAccess(i, j, chunkStatus, bl);
|
ChunkAccess chunk = getChunkAccess(i, j, chunkStatus, bl);
|
||||||
if (chunk instanceof LevelChunk) {
|
if (chunk instanceof LevelChunk) {
|
||||||
chunk = new ImposterProtoChunk((LevelChunk) chunk, true);
|
chunk = new ImposterProtoChunk((LevelChunk) chunk #if POST_MC_1_18_1, true #endif);
|
||||||
}
|
}
|
||||||
return chunk;
|
return chunk;
|
||||||
}
|
}
|
||||||
@@ -197,7 +249,7 @@ public class LightedWorldGenRegion extends WorldGenRegion {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (chunkStatus != ChunkStatus.EMPTY && chunkStatus != debugTriggeredForStatus) {
|
if (chunkStatus != ChunkStatus.EMPTY && chunkStatus != debugTriggeredForStatus) {
|
||||||
ApiShared.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;
|
||||||
}
|
}
|
||||||
@@ -213,7 +265,7 @@ public class LightedWorldGenRegion extends WorldGenRegion {
|
|||||||
// Override force use of my own light engine
|
// Override force use of my own light engine
|
||||||
@Override
|
@Override
|
||||||
public int getBrightness(LightLayer lightLayer, BlockPos blockPos) {
|
public int getBrightness(LightLayer lightLayer, BlockPos blockPos) {
|
||||||
if (lightMode != LightGenerationMode.FAST) {
|
if (lightMode != ELightGenerationMode.FAST) {
|
||||||
return light.getLayerListener(lightLayer).getLightValue(blockPos);
|
return light.getLayerListener(lightLayer).getLightValue(blockPos);
|
||||||
}
|
}
|
||||||
if (lightLayer == LightLayer.BLOCK)
|
if (lightLayer == LightLayer.BLOCK)
|
||||||
@@ -225,7 +277,7 @@ public class LightedWorldGenRegion extends WorldGenRegion {
|
|||||||
// Override force use of my own light engine
|
// Override force use of my own light engine
|
||||||
@Override
|
@Override
|
||||||
public int getRawBrightness(BlockPos blockPos, int i) {
|
public int getRawBrightness(BlockPos blockPos, int i) {
|
||||||
if (lightMode != LightGenerationMode.FAST) {
|
if (lightMode != ELightGenerationMode.FAST) {
|
||||||
return light.getRawBrightness(blockPos, i);
|
return light.getRawBrightness(blockPos, i);
|
||||||
}
|
}
|
||||||
BlockPos p = super.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, blockPos);
|
BlockPos p = super.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, blockPos);
|
||||||
@@ -237,28 +289,27 @@ public class LightedWorldGenRegion extends WorldGenRegion {
|
|||||||
public boolean canSeeSky(BlockPos blockPos) {
|
public boolean canSeeSky(BlockPos blockPos) {
|
||||||
return (getBrightness(LightLayer.SKY, blockPos) >= getMaxLightLevel());
|
return (getBrightness(LightLayer.SKY, blockPos) >= getMaxLightLevel());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private final Object2ObjectArrayMap<ColorResolver, BlockTintCache> tintCaches;
|
|
||||||
|
|
||||||
public int getBlockTint(BlockPos blockPos, ColorResolver colorResolver)
|
public int getBlockTint(BlockPos blockPos, ColorResolver colorResolver)
|
||||||
{
|
{
|
||||||
BlockTintCache blockTintCache = (BlockTintCache) this.tintCaches.get(colorResolver);
|
return calculateBlockTint(blockPos, colorResolver);
|
||||||
return blockTintCache.getColor(blockPos);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Biome _getBiome(BlockPos pos) {
|
private Biome _getBiome(BlockPos pos) {
|
||||||
#if MC_VERSION_1_18_2
|
#if POST_MC_1_18_2
|
||||||
return getBiome(pos).value();
|
return getBiome(pos).value();
|
||||||
#elif MC_VERSION_1_18_1
|
#else
|
||||||
return getBiome(pos);
|
return getBiome(pos);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
public int calculateBlockTint(BlockPos blockPos, ColorResolver colorResolver)
|
public int calculateBlockTint(BlockPos blockPos, ColorResolver colorResolver)
|
||||||
{
|
{
|
||||||
|
#if PRE_MC_1_19
|
||||||
int i = (Minecraft.getInstance()).options.biomeBlendRadius;
|
int i = (Minecraft.getInstance()).options.biomeBlendRadius;
|
||||||
|
#else
|
||||||
|
int i = (Minecraft.getInstance()).options.biomeBlendRadius().get();
|
||||||
|
#endif
|
||||||
if (i == 0)
|
if (i == 0)
|
||||||
return colorResolver.getColor((Biome) _getBiome(blockPos), blockPos.getX(), blockPos.getZ());
|
return colorResolver.getColor((Biome) _getBiome(blockPos), blockPos.getX(), blockPos.getZ());
|
||||||
int j = (i * 2 + 1) * (i * 2 + 1);
|
int j = (i * 2 + 1) * (i * 2 + 1);
|
||||||
|
|||||||
+48
-3
@@ -1,3 +1,22 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
|
||||||
|
* licensed under the GNU LGPL v3 License.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2020-2022 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.lod.common.wrappers.worldGeneration.mimicObject;
|
package com.seibel.lod.common.wrappers.worldGeneration.mimicObject;
|
||||||
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
@@ -5,7 +24,9 @@ import org.jetbrains.annotations.Nullable;
|
|||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.core.SectionPos;
|
import net.minecraft.core.SectionPos;
|
||||||
import net.minecraft.world.level.ChunkPos;
|
import net.minecraft.world.level.ChunkPos;
|
||||||
|
#if POST_MC_1_17_1
|
||||||
import net.minecraft.world.level.LevelHeightAccessor;
|
import net.minecraft.world.level.LevelHeightAccessor;
|
||||||
|
#endif
|
||||||
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.DataLayer;
|
import net.minecraft.world.level.chunk.DataLayer;
|
||||||
@@ -18,7 +39,9 @@ import net.minecraft.world.level.lighting.SkyLightEngine;
|
|||||||
public class WorldGenLevelLightEngine extends LevelLightEngine {
|
public class WorldGenLevelLightEngine extends LevelLightEngine {
|
||||||
public static final int MAX_SOURCE_LEVEL = 15;
|
public static final int MAX_SOURCE_LEVEL = 15;
|
||||||
public static final int LIGHT_SECTION_PADDING = 1;
|
public static final int LIGHT_SECTION_PADDING = 1;
|
||||||
|
#if POST_MC_1_17_1
|
||||||
protected final LevelHeightAccessor levelHeightAccessor;
|
protected final LevelHeightAccessor levelHeightAccessor;
|
||||||
|
#endif
|
||||||
@Nullable
|
@Nullable
|
||||||
public final BlockLightEngine blockEngine;
|
public final BlockLightEngine blockEngine;
|
||||||
@Nullable
|
@Nullable
|
||||||
@@ -26,7 +49,9 @@ public class WorldGenLevelLightEngine extends LevelLightEngine {
|
|||||||
|
|
||||||
public WorldGenLevelLightEngine(LightGetterAdaptor genRegion) {
|
public WorldGenLevelLightEngine(LightGetterAdaptor genRegion) {
|
||||||
super(genRegion, false, false);
|
super(genRegion, false, false);
|
||||||
|
#if POST_MC_1_17_1
|
||||||
this.levelHeightAccessor = genRegion.getLevelHeightAccessor();
|
this.levelHeightAccessor = genRegion.getLevelHeightAccessor();
|
||||||
|
#endif
|
||||||
this.blockEngine = new BlockLightEngine(genRegion);
|
this.blockEngine = new BlockLightEngine(genRegion);
|
||||||
this.skyEngine = new SkyLightEngine(genRegion);
|
this.skyEngine = new SkyLightEngine(genRegion);
|
||||||
}
|
}
|
||||||
@@ -123,18 +148,35 @@ public class WorldGenLevelLightEngine extends LevelLightEngine {
|
|||||||
chunkAccess.setLightCorrect(false);
|
chunkAccess.setLightCorrect(false);
|
||||||
|
|
||||||
LevelChunkSection[] levelChunkSections = chunkAccess.getSections();
|
LevelChunkSection[] levelChunkSections = chunkAccess.getSections();
|
||||||
for (int i = 0; i < chunkAccess.getSectionsCount(); ++i) {
|
for (int i = 0; i <
|
||||||
|
#if POST_MC_1_17_1
|
||||||
|
chunkAccess.getSectionsCount()
|
||||||
|
#else
|
||||||
|
16
|
||||||
|
#endif
|
||||||
|
; ++i) {
|
||||||
LevelChunkSection levelChunkSection = levelChunkSections[i];
|
LevelChunkSection levelChunkSection = levelChunkSections[i];
|
||||||
|
#if PRE_MC_1_17_1
|
||||||
|
if (!LevelChunkSection.isEmpty(levelChunkSection)) {
|
||||||
|
updateSectionStatus(SectionPos.of(chunkPos, i), false);
|
||||||
|
}
|
||||||
|
#elif PRE_MC_1_18_1
|
||||||
|
if (!LevelChunkSection.isEmpty(levelChunkSection)) {
|
||||||
|
int j = this.levelHeightAccessor.getSectionYFromSectionIndex(i);
|
||||||
|
updateSectionStatus(SectionPos.of(chunkPos, j), false);
|
||||||
|
}
|
||||||
|
#else
|
||||||
if (levelChunkSection.hasOnlyAir()) continue;
|
if (levelChunkSection.hasOnlyAir()) continue;
|
||||||
int j = this.levelHeightAccessor.getSectionYFromSectionIndex(i);
|
int j = this.levelHeightAccessor.getSectionYFromSectionIndex(i);
|
||||||
updateSectionStatus(SectionPos.of(chunkPos, j), false);
|
updateSectionStatus(SectionPos.of(chunkPos, j), false);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
enableLightSources(chunkPos, true);
|
enableLightSources(chunkPos, true);
|
||||||
if (needLightBlockUpdate) {
|
if (needLightBlockUpdate) {
|
||||||
chunkAccess.getLights().forEach(blockPos ->
|
chunkAccess.getLights().forEach(blockPos ->
|
||||||
onBlockEmissionIncrease(blockPos, chunkAccess.getLightEmission(blockPos)));
|
onBlockEmissionIncrease(blockPos, chunkAccess.getLightEmission(blockPos)));
|
||||||
}
|
}
|
||||||
|
|
||||||
chunkAccess.setLightCorrect(true);
|
chunkAccess.setLightCorrect(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -161,6 +203,8 @@ public class WorldGenLevelLightEngine extends LevelLightEngine {
|
|||||||
this.skyEngine.retainData(chunkPos, bl);
|
this.skyEngine.retainData(chunkPos, bl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if POST_MC_1_17_1
|
||||||
@Override
|
@Override
|
||||||
public int getLightSectionCount() {
|
public int getLightSectionCount() {
|
||||||
throw new UnsupportedOperationException("This should never be used!");
|
throw new UnsupportedOperationException("This should never be used!");
|
||||||
@@ -173,4 +217,5 @@ public class WorldGenLevelLightEngine extends LevelLightEngine {
|
|||||||
public int getMaxLightSection() {
|
public int getMaxLightSection() {
|
||||||
throw new UnsupportedOperationException("This should never be used!");
|
throw new UnsupportedOperationException("This should never be used!");
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
+191
-44
@@ -1,6 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
|
||||||
|
* licensed under the GNU LGPL v3 License.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2020-2022 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.lod.common.wrappers.worldGeneration.mimicObject;
|
package com.seibel.lod.common.wrappers.worldGeneration.mimicObject;
|
||||||
|
|
||||||
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
@@ -12,71 +37,193 @@ import net.minecraft.core.SectionPos;
|
|||||||
import net.minecraft.server.level.WorldGenRegion;
|
import net.minecraft.server.level.WorldGenRegion;
|
||||||
import net.minecraft.world.level.ChunkPos;
|
import net.minecraft.world.level.ChunkPos;
|
||||||
import net.minecraft.world.level.LevelAccessor;
|
import net.minecraft.world.level.LevelAccessor;
|
||||||
import net.minecraft.world.level.StructureFeatureManager;
|
|
||||||
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.chunk.ChunkStatus;
|
||||||
import net.minecraft.world.level.levelgen.WorldGenSettings;
|
import net.minecraft.world.level.levelgen.WorldGenSettings;
|
||||||
|
#if PRE_MC_1_19
|
||||||
|
import net.minecraft.world.level.levelgen.feature.ConfiguredStructureFeature;
|
||||||
import net.minecraft.world.level.levelgen.feature.StructureFeature;
|
import net.minecraft.world.level.levelgen.feature.StructureFeature;
|
||||||
|
import net.minecraft.world.level.StructureFeatureManager;
|
||||||
|
#else
|
||||||
|
import net.minecraft.world.level.levelgen.structure.Structure;
|
||||||
|
import net.minecraft.world.level.StructureManager;
|
||||||
|
#endif
|
||||||
|
#if POST_MC_1_18_1
|
||||||
import net.minecraft.world.level.levelgen.structure.StructureCheck;
|
import net.minecraft.world.level.levelgen.structure.StructureCheck;
|
||||||
|
#endif
|
||||||
import net.minecraft.world.level.levelgen.structure.StructureStart;
|
import net.minecraft.world.level.levelgen.structure.StructureStart;
|
||||||
|
|
||||||
|
#if PRE_MC_1_19
|
||||||
public class WorldGenStructFeatManager extends StructureFeatureManager {
|
public class WorldGenStructFeatManager extends StructureFeatureManager {
|
||||||
WorldGenLevel genLevel;
|
#else
|
||||||
|
public class WorldGenStructFeatManager extends StructureManager {
|
||||||
|
#endif
|
||||||
|
final WorldGenLevel genLevel;
|
||||||
WorldGenSettings worldGenSettings;
|
WorldGenSettings worldGenSettings;
|
||||||
|
#if POST_MC_1_18_1
|
||||||
StructureCheck structureCheck;
|
StructureCheck structureCheck;
|
||||||
public WorldGenStructFeatManager(LevelAccessor levelAccessor, WorldGenSettings worldGenSettings,
|
|
||||||
WorldGenLevel genLevel, StructureCheck structureCheck) {
|
#endif
|
||||||
super(levelAccessor, worldGenSettings, structureCheck);
|
public WorldGenStructFeatManager(WorldGenSettings worldGenSettings,
|
||||||
|
WorldGenLevel genLevel #if POST_MC_1_18_1 , StructureCheck structureCheck #endif ) {
|
||||||
|
|
||||||
|
super(genLevel, worldGenSettings #if POST_MC_1_18_1 , structureCheck #endif );
|
||||||
this.genLevel = genLevel;
|
this.genLevel = genLevel;
|
||||||
this.worldGenSettings = worldGenSettings;
|
this.worldGenSettings = worldGenSettings;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setGenLevel(WorldGenLevel genLevel) {
|
|
||||||
this.genLevel = genLevel;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public WorldGenStructFeatManager forWorldGenRegion(WorldGenRegion worldGenRegion) {
|
public WorldGenStructFeatManager forWorldGenRegion(WorldGenRegion worldGenRegion) {
|
||||||
if (worldGenRegion == genLevel)
|
if (worldGenRegion == genLevel)
|
||||||
return this;
|
return this;
|
||||||
return new WorldGenStructFeatManager(worldGenRegion, worldGenSettings, worldGenRegion, structureCheck);
|
return new WorldGenStructFeatManager(worldGenSettings, worldGenRegion #if POST_MC_1_18_1 , structureCheck #endif );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ChunkAccess _getChunk(int x, int z, ChunkStatus status) {
|
||||||
|
if (genLevel == null) return null;
|
||||||
|
return genLevel.getChunk(x, z, status, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if PRE_MC_1_18_1
|
||||||
@Override
|
@Override
|
||||||
public boolean hasAnyStructureAt(BlockPos blockPos) {
|
public Stream<? extends StructureStart<?>> startsForFeature(SectionPos sectionPos2,
|
||||||
SectionPos sectionPos = SectionPos.of(blockPos);
|
StructureFeature<?> structureFeature) {
|
||||||
ChunkAccess chunk = genLevel.getChunk(sectionPos.x(), sectionPos.z(), ChunkStatus.STRUCTURE_REFERENCES,
|
ChunkAccess chunk = _getChunk(sectionPos2.x(), sectionPos2.z(), ChunkStatus.STRUCTURE_REFERENCES);
|
||||||
false);
|
if (chunk == null) return Stream.empty();
|
||||||
|
|
||||||
|
return chunk.getReferencesForFeature(structureFeature).stream().map(pos -> {
|
||||||
|
SectionPos sectPos = SectionPos.of(ChunkPos.getX(pos), 0, ChunkPos.getZ(pos));
|
||||||
|
ChunkAccess startChunk = _getChunk(sectPos.x(), sectPos.z(), ChunkStatus.STRUCTURE_STARTS);
|
||||||
|
if (startChunk == null) return null;
|
||||||
|
return this.getStartForFeature(sectPos, structureFeature, startChunk);
|
||||||
|
}).filter(structureStart -> structureStart != null && structureStart.isValid());
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
@Override
|
||||||
|
public boolean hasAnyStructureAt(BlockPos blockPos) {
|
||||||
|
SectionPos sectionPos = SectionPos.of(blockPos);
|
||||||
|
ChunkAccess chunk = _getChunk(sectionPos.x(), sectionPos.z(), ChunkStatus.STRUCTURE_REFERENCES);
|
||||||
if (chunk == null) return false;
|
if (chunk == null) return false;
|
||||||
return chunk.hasAnyStructureReferences();
|
return chunk.hasAnyStructureReferences();
|
||||||
}
|
|
||||||
|
|
||||||
// TODO Check this
|
|
||||||
/*
|
|
||||||
@Override
|
|
||||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
|
||||||
public List<? extends StructureStart<?>> startsForFeature(SectionPos sectionPos,
|
|
||||||
StructureFeature<?> structureFeature) {
|
|
||||||
if (genLevel == null)
|
|
||||||
return List.of();
|
|
||||||
ChunkAccess chunk = genLevel.getChunk(sectionPos.x(), sectionPos.z(), ChunkStatus.STRUCTURE_REFERENCES,
|
|
||||||
false);
|
|
||||||
if (chunk == null)
|
|
||||||
return List.of();
|
|
||||||
LongSet longSet = chunk.getReferencesForFeature(structureFeature);
|
|
||||||
ImmutableList.Builder builder = ImmutableList.builder();
|
|
||||||
LongIterator longIterator = longSet.iterator();
|
|
||||||
while (longIterator.hasNext()) {
|
|
||||||
long l = (Long)longIterator.next();
|
|
||||||
SectionPos sectPos = SectionPos.of(new ChunkPos(l), genLevel.getMinSection());
|
|
||||||
ChunkAccess startChunk = genLevel.getChunk(sectPos.x(), sectPos.z(), ChunkStatus.STRUCTURE_STARTS, false);
|
|
||||||
if (startChunk == null) continue;
|
|
||||||
StructureStart<?> structureStart = this.getStartForFeature(sectPos, structureFeature, startChunk);
|
|
||||||
if (structureStart == null || !structureStart.isValid()) continue;
|
|
||||||
builder.add(structureStart);
|
|
||||||
}
|
|
||||||
return builder.build();
|
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
}
|
#if MC_1_18_1
|
||||||
|
@Override
|
||||||
|
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||||
|
public List<? extends StructureStart<?>> startsForFeature(SectionPos sectionPos,
|
||||||
|
StructureFeature<?> structureFeature) {
|
||||||
|
|
||||||
|
ChunkAccess chunk = _getChunk(sectionPos.x(), sectionPos.z(), ChunkStatus.STRUCTURE_REFERENCES);
|
||||||
|
if (chunk == null) return List.of();
|
||||||
|
|
||||||
|
// Copied from StructureFeatureManager::startsForFeature(...) with slight tweaks
|
||||||
|
LongSet longSet = chunk.getReferencesForFeature(structureFeature);
|
||||||
|
ImmutableList.Builder builder = ImmutableList.builder();
|
||||||
|
LongIterator longIterator = longSet.iterator();
|
||||||
|
while (longIterator.hasNext()) {
|
||||||
|
long l = (Long)longIterator.next();
|
||||||
|
SectionPos sectPos = SectionPos.of(new ChunkPos(l), genLevel.getMinSection());
|
||||||
|
ChunkAccess startChunk = _getChunk(sectPos.x(), sectPos.z(), ChunkStatus.STRUCTURE_STARTS);
|
||||||
|
if (startChunk == null) continue;
|
||||||
|
StructureStart<?> structureStart = this.getStartForFeature(sectPos, structureFeature, startChunk);
|
||||||
|
if (structureStart == null || !structureStart.isValid()) continue;
|
||||||
|
builder.add(structureStart);
|
||||||
|
}
|
||||||
|
return builder.build();
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#if PRE_MC_1_19
|
||||||
|
@Override
|
||||||
|
public List<StructureStart> startsForFeature(SectionPos sectionPos, Predicate<ConfiguredStructureFeature<?, ?>> predicate) {
|
||||||
|
ChunkAccess chunk = _getChunk(sectionPos.x(), sectionPos.z(), ChunkStatus.STRUCTURE_REFERENCES);
|
||||||
|
if (chunk == null) return List.of();
|
||||||
|
|
||||||
|
// Copied from StructureFeatureManager::startsForFeature(...)
|
||||||
|
Map<ConfiguredStructureFeature<?, ?>, LongSet> map = chunk.getAllReferences();
|
||||||
|
|
||||||
|
ImmutableList.Builder<StructureStart> builder = ImmutableList.builder();
|
||||||
|
Iterator<Map.Entry<ConfiguredStructureFeature<?, ?>, LongSet>> var5 = map.entrySet().iterator();
|
||||||
|
|
||||||
|
while(var5.hasNext()) {
|
||||||
|
Map.Entry<ConfiguredStructureFeature<?, ?>, LongSet> entry = var5.next();
|
||||||
|
ConfiguredStructureFeature<?, ?> configuredStructureFeature = entry.getKey();
|
||||||
|
if (predicate.test(configuredStructureFeature)) {
|
||||||
|
LongSet var10002 = (LongSet)entry.getValue();
|
||||||
|
Objects.requireNonNull(builder);
|
||||||
|
this.fillStartsForFeature(configuredStructureFeature, var10002, builder::add);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return builder.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<StructureStart> startsForFeature(SectionPos sectionPos, ConfiguredStructureFeature<?, ?> configuredStructureFeature) {
|
||||||
|
ChunkAccess chunk = _getChunk(sectionPos.x(), sectionPos.z(), ChunkStatus.STRUCTURE_REFERENCES);
|
||||||
|
if (chunk == null) return (List<StructureStart>) Stream.empty();
|
||||||
|
|
||||||
|
// Copied from StructureFeatureManager::startsForFeature(...)
|
||||||
|
LongSet longSet = chunk.getReferencesForFeature(configuredStructureFeature);
|
||||||
|
ImmutableList.Builder<StructureStart> builder = ImmutableList.builder();
|
||||||
|
Objects.requireNonNull(builder);
|
||||||
|
this.fillStartsForFeature(configuredStructureFeature, longSet, builder::add);
|
||||||
|
return builder.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<ConfiguredStructureFeature<?, ?>, LongSet> getAllStructuresAt(BlockPos blockPos) {
|
||||||
|
SectionPos sectionPos = SectionPos.of(blockPos);
|
||||||
|
ChunkAccess chunk = _getChunk(sectionPos.x(), sectionPos.z(), ChunkStatus.STRUCTURE_REFERENCES);
|
||||||
|
if (chunk == null) return (Map<ConfiguredStructureFeature<?, ?>, LongSet>) Stream.empty();
|
||||||
|
return chunk.getAllReferences();
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
@Override
|
||||||
|
public List<StructureStart> startsForStructure(ChunkPos sectionPos, Predicate<Structure> predicate) {
|
||||||
|
ChunkAccess chunk = _getChunk(sectionPos.x, sectionPos.z, ChunkStatus.STRUCTURE_REFERENCES);
|
||||||
|
if (chunk == null) return List.of();
|
||||||
|
|
||||||
|
// Copied from StructureFeatureManager::startsForFeature(...)
|
||||||
|
Map<Structure, LongSet> map = chunk.getAllReferences();
|
||||||
|
|
||||||
|
ImmutableList.Builder<StructureStart> builder = ImmutableList.builder();
|
||||||
|
Iterator<Map.Entry<Structure, LongSet>> var5 = map.entrySet().iterator();
|
||||||
|
|
||||||
|
while (var5.hasNext()) {
|
||||||
|
Map.Entry<Structure, LongSet> entry = var5.next();
|
||||||
|
Structure configuredStructureFeature = entry.getKey();
|
||||||
|
if (predicate.test(configuredStructureFeature)) {
|
||||||
|
LongSet var10002 = (LongSet) entry.getValue();
|
||||||
|
Objects.requireNonNull(builder);
|
||||||
|
this.fillStartsForStructure(configuredStructureFeature, var10002, builder::add);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return builder.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<StructureStart> startsForStructure(SectionPos sectionPos, Structure structure) {
|
||||||
|
ChunkAccess chunk = _getChunk(sectionPos.x(), sectionPos.z(), ChunkStatus.STRUCTURE_REFERENCES);
|
||||||
|
if (chunk == null) return (List<StructureStart>) Stream.empty();
|
||||||
|
|
||||||
|
// Copied from StructureFeatureManager::startsForFeature(...)
|
||||||
|
LongSet longSet = chunk.getReferencesForStructure(structure);
|
||||||
|
ImmutableList.Builder<StructureStart> builder = ImmutableList.builder();
|
||||||
|
Objects.requireNonNull(builder);
|
||||||
|
this.fillStartsForStructure(structure, longSet, builder::add);
|
||||||
|
return builder.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<Structure, LongSet> getAllStructuresAt(BlockPos blockPos) {
|
||||||
|
SectionPos sectionPos = SectionPos.of(blockPos);
|
||||||
|
ChunkAccess chunk = _getChunk(sectionPos.x(), sectionPos.z(), ChunkStatus.STRUCTURE_REFERENCES);
|
||||||
|
if (chunk == null) return (Map<Structure, LongSet>) Stream.empty();
|
||||||
|
return chunk.getAllReferences();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|||||||
+30
@@ -1,3 +1,22 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
|
||||||
|
* licensed under the GNU LGPL v3 License.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2020-2022 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.lod.common.wrappers.worldGeneration.step;
|
package com.seibel.lod.common.wrappers.worldGeneration.step;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -8,7 +27,9 @@ import com.seibel.lod.common.wrappers.worldGeneration.ThreadedParameters;
|
|||||||
|
|
||||||
import net.minecraft.core.Registry;
|
import net.minecraft.core.Registry;
|
||||||
import net.minecraft.server.level.WorldGenRegion;
|
import net.minecraft.server.level.WorldGenRegion;
|
||||||
|
#if PRE_MC_1_19
|
||||||
import net.minecraft.world.level.StructureFeatureManager;
|
import net.minecraft.world.level.StructureFeatureManager;
|
||||||
|
#endif
|
||||||
import net.minecraft.world.level.biome.Biome;
|
import net.minecraft.world.level.biome.Biome;
|
||||||
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;
|
||||||
@@ -17,7 +38,9 @@ import net.minecraft.world.level.chunk.ProtoChunk;
|
|||||||
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;
|
||||||
import net.minecraft.world.level.levelgen.NoiseBasedChunkGenerator;
|
import net.minecraft.world.level.levelgen.NoiseBasedChunkGenerator;
|
||||||
|
#if POST_MC_1_18_1
|
||||||
import net.minecraft.world.level.levelgen.blending.Blender;
|
import net.minecraft.world.level.levelgen.blending.Blender;
|
||||||
|
#endif
|
||||||
|
|
||||||
public final class StepBiomes {
|
public final class StepBiomes {
|
||||||
/**
|
/**
|
||||||
@@ -48,8 +71,15 @@ public final class StepBiomes {
|
|||||||
|
|
||||||
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_1
|
||||||
|
environment.params.generator.createBiomes(environment.params.biomes, chunk);
|
||||||
|
#elif PRE_MC_1_19
|
||||||
chunk = environment.joinSync(environment.params.generator.createBiomes(environment.params.biomes, Runnable::run, Blender.of(worldGenRegion),
|
chunk = environment.joinSync(environment.params.generator.createBiomes(environment.params.biomes, Runnable::run, Blender.of(worldGenRegion),
|
||||||
tParams.structFeat.forWorldGenRegion(worldGenRegion), chunk));
|
tParams.structFeat.forWorldGenRegion(worldGenRegion), chunk));
|
||||||
|
#else
|
||||||
|
chunk = environment.joinSync(environment.params.generator.createBiomes(environment.params.biomes, Runnable::run, environment.params.randomState, Blender.of(worldGenRegion),
|
||||||
|
tParams.structFeat.forWorldGenRegion(worldGenRegion), chunk));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+34
-11
@@ -1,9 +1,29 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
|
||||||
|
* licensed under the GNU LGPL v3 License.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2020-2022 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.lod.common.wrappers.worldGeneration.step;
|
package com.seibel.lod.common.wrappers.worldGeneration.step;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
import com.seibel.lod.common.wrappers.worldGeneration.BatchGenerationEnvironment;
|
import com.seibel.lod.common.wrappers.worldGeneration.BatchGenerationEnvironment;
|
||||||
import com.seibel.lod.common.wrappers.worldGeneration.ThreadedParameters;
|
import com.seibel.lod.common.wrappers.worldGeneration.ThreadedParameters;
|
||||||
|
import com.seibel.lod.common.wrappers.worldGeneration.mimicObject.LightedWorldGenRegion;
|
||||||
import com.seibel.lod.core.util.gridList.ArrayGridList;
|
import com.seibel.lod.core.util.gridList.ArrayGridList;
|
||||||
|
|
||||||
import net.minecraft.ReportedException;
|
import net.minecraft.ReportedException;
|
||||||
@@ -11,7 +31,10 @@ 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.ChunkStatus;
|
||||||
import net.minecraft.world.level.chunk.ProtoChunk;
|
import net.minecraft.world.level.chunk.ProtoChunk;
|
||||||
|
import net.minecraft.world.level.levelgen.Heightmap;
|
||||||
|
#if POST_MC_1_18_1
|
||||||
import net.minecraft.world.level.levelgen.blending.Blender;
|
import net.minecraft.world.level.levelgen.blending.Blender;
|
||||||
|
#endif
|
||||||
|
|
||||||
public final class StepFeatures {
|
public final class StepFeatures {
|
||||||
/**
|
/**
|
||||||
@@ -29,7 +52,7 @@ public final class StepFeatures {
|
|||||||
|
|
||||||
public final ChunkStatus STATUS = ChunkStatus.FEATURES;
|
public final ChunkStatus STATUS = ChunkStatus.FEATURES;
|
||||||
|
|
||||||
public void generateGroup(ThreadedParameters tParams, WorldGenRegion worldGenRegion,
|
public void generateGroup(ThreadedParameters tParams, LightedWorldGenRegion worldGenRegion,
|
||||||
ArrayGridList<ChunkAccess> chunks) {
|
ArrayGridList<ChunkAccess> chunks) {
|
||||||
ArrayList<ChunkAccess> chunksToDo = new ArrayList<ChunkAccess>();
|
ArrayList<ChunkAccess> chunksToDo = new ArrayList<ChunkAccess>();
|
||||||
|
|
||||||
@@ -41,20 +64,20 @@ public final class StepFeatures {
|
|||||||
|
|
||||||
for (ChunkAccess chunk : chunksToDo) {
|
for (ChunkAccess chunk : chunksToDo) {
|
||||||
try {
|
try {
|
||||||
|
#if PRE_MC_1_18_1
|
||||||
|
worldGenRegion.setOverrideCenter(chunk.getPos());
|
||||||
|
Heightmap.primeHeightmaps(chunk, STATUS.heightmapsAfter());
|
||||||
|
environment.params.generator.applyBiomeDecoration(worldGenRegion, tParams.structFeat);
|
||||||
|
#else
|
||||||
|
Heightmap.primeHeightmaps(chunk, STATUS.heightmapsAfter());
|
||||||
environment.params.generator.applyBiomeDecoration(worldGenRegion, chunk,
|
environment.params.generator.applyBiomeDecoration(worldGenRegion, chunk,
|
||||||
tParams.structFeat.forWorldGenRegion(worldGenRegion));
|
tParams.structFeat.forWorldGenRegion(worldGenRegion));
|
||||||
Blender.generateBorderTicks(worldGenRegion, chunk);
|
#endif
|
||||||
} catch (ReportedException e) {
|
} catch (ReportedException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
// FIXME: Features concurrent modification issue. Something about cocobeans just
|
// FIXME: Features concurrent modification issue. Something about cocobeans might just
|
||||||
// aren't happy
|
// error out. For now just retry.
|
||||||
// For now just retry.
|
|
||||||
}
|
}
|
||||||
}/*
|
}
|
||||||
for (ChunkAccess chunk : chunks) {
|
|
||||||
Heightmap.primeHeightmaps(chunk,
|
|
||||||
EnumSet.of(Heightmap.Types.MOTION_BLOCKING, Heightmap.Types.MOTION_BLOCKING_NO_LEAVES,
|
|
||||||
Heightmap.Types.OCEAN_FLOOR, Heightmap.Types.WORLD_SURFACE));
|
|
||||||
}*/
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+25
-2
@@ -1,3 +1,22 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
|
||||||
|
* licensed under the GNU LGPL v3 License.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2020-2022 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.lod.common.wrappers.worldGeneration.step;
|
package com.seibel.lod.common.wrappers.worldGeneration.step;
|
||||||
|
|
||||||
import com.seibel.lod.common.wrappers.worldGeneration.BatchGenerationEnvironment;
|
import com.seibel.lod.common.wrappers.worldGeneration.BatchGenerationEnvironment;
|
||||||
@@ -9,6 +28,7 @@ import net.minecraft.world.level.chunk.ChunkAccess;
|
|||||||
import net.minecraft.world.level.chunk.ChunkStatus;
|
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.lighting.LevelLightEngine;
|
||||||
import net.minecraft.world.level.lighting.LightEventListener;
|
import net.minecraft.world.level.lighting.LightEventListener;
|
||||||
|
|
||||||
public final class StepLight {
|
public final class StepLight {
|
||||||
@@ -27,9 +47,10 @@ public final class StepLight {
|
|||||||
|
|
||||||
public final ChunkStatus STATUS = ChunkStatus.LIGHT;
|
public final ChunkStatus STATUS = ChunkStatus.LIGHT;
|
||||||
|
|
||||||
public void generateGroup(LightEventListener lightEngine,
|
public void generateGroup(
|
||||||
|
#if PRE_MC_1_17_1 LevelLightEngine lightEngine,
|
||||||
|
#else LightEventListener lightEngine, #endif
|
||||||
ArrayGridList<ChunkAccess> chunks) {
|
ArrayGridList<ChunkAccess> chunks) {
|
||||||
//ArrayList<ChunkAccess> chunksToDo = new ArrayList<ChunkAccess>();
|
|
||||||
|
|
||||||
for (ChunkAccess chunk : chunks) {
|
for (ChunkAccess chunk : chunks) {
|
||||||
if (chunk.getStatus().isOrAfter(STATUS)) continue;
|
if (chunk.getStatus().isOrAfter(STATUS)) continue;
|
||||||
@@ -52,7 +73,9 @@ public final class StepLight {
|
|||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
#if POST_MC_1_18_1
|
||||||
if (chunk instanceof LevelChunk) ((LevelChunk)chunk).setClientLightReady(true);
|
if (chunk instanceof LevelChunk) ((LevelChunk)chunk).setClientLightReady(true);
|
||||||
|
#endif
|
||||||
chunk.setLightCorrect(true);
|
chunk.setLightCorrect(true);
|
||||||
}
|
}
|
||||||
lightEngine.runUpdates(Integer.MAX_VALUE, true, true);
|
lightEngine.runUpdates(Integer.MAX_VALUE, true, true);
|
||||||
|
|||||||
+38
-10
@@ -1,25 +1,42 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
|
||||||
|
* licensed under the GNU LGPL v3 License.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2020-2022 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.lod.common.wrappers.worldGeneration.step;
|
package com.seibel.lod.common.wrappers.worldGeneration.step;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.CompletableFuture;
|
|
||||||
|
|
||||||
import com.google.common.collect.Sets;
|
|
||||||
import com.seibel.lod.common.wrappers.worldGeneration.BatchGenerationEnvironment;
|
import com.seibel.lod.common.wrappers.worldGeneration.BatchGenerationEnvironment;
|
||||||
import com.seibel.lod.common.wrappers.worldGeneration.ThreadedParameters;
|
import com.seibel.lod.common.wrappers.worldGeneration.ThreadedParameters;
|
||||||
|
|
||||||
|
import com.seibel.lod.core.util.objects.UncheckedInterruptedException;
|
||||||
import net.minecraft.server.level.WorldGenRegion;
|
import net.minecraft.server.level.WorldGenRegion;
|
||||||
import net.minecraft.util.Mth;
|
#if POST_MC_1_17_1
|
||||||
import net.minecraft.world.level.LevelHeightAccessor;
|
#endif
|
||||||
import net.minecraft.world.level.StructureFeatureManager;
|
#if PRE_MC_1_19
|
||||||
|
#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.ChunkStatus;
|
||||||
import net.minecraft.world.level.chunk.LevelChunkSection;
|
|
||||||
import net.minecraft.world.level.chunk.ProtoChunk;
|
import net.minecraft.world.level.chunk.ProtoChunk;
|
||||||
import net.minecraft.world.level.levelgen.NoiseBasedChunkGenerator;
|
#if POST_MC_1_18_1
|
||||||
import net.minecraft.world.level.levelgen.NoiseSettings;
|
|
||||||
import net.minecraft.world.level.levelgen.blending.Blender;
|
import net.minecraft.world.level.levelgen.blending.Blender;
|
||||||
|
#endif
|
||||||
|
|
||||||
public final class StepNoise {
|
public final class StepNoise {
|
||||||
/**
|
/**
|
||||||
@@ -50,8 +67,19 @@ public final class StepNoise {
|
|||||||
|
|
||||||
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
|
||||||
|
environment.params.generator.fillFromNoise(worldGenRegion, tParams.structFeat, chunk);
|
||||||
|
#elif PRE_MC_1_18_1
|
||||||
|
chunk = environment.joinSync(environment.params.generator.fillFromNoise(Runnable::run,
|
||||||
|
tParams.structFeat.forWorldGenRegion(worldGenRegion), chunk));
|
||||||
|
#elif PRE_MC_1_19
|
||||||
chunk = environment.joinSync(environment.params.generator.fillFromNoise(Runnable::run, Blender.of(worldGenRegion),
|
chunk = environment.joinSync(environment.params.generator.fillFromNoise(Runnable::run, Blender.of(worldGenRegion),
|
||||||
tParams.structFeat.forWorldGenRegion(worldGenRegion), chunk));
|
tParams.structFeat.forWorldGenRegion(worldGenRegion), chunk));
|
||||||
|
#else
|
||||||
|
chunk = environment.joinSync(environment.params.generator.fillFromNoise(Runnable::run, Blender.of(worldGenRegion), environment.params.randomState,
|
||||||
|
tParams.structFeat.forWorldGenRegion(worldGenRegion), chunk));
|
||||||
|
#endif
|
||||||
|
UncheckedInterruptedException.throwIfInterrupted();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+21
@@ -1,3 +1,22 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
|
||||||
|
* licensed under the GNU LGPL v3 License.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2020-2022 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.lod.common.wrappers.worldGeneration.step;
|
package com.seibel.lod.common.wrappers.worldGeneration.step;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -13,7 +32,9 @@ import net.minecraft.core.Registry;
|
|||||||
import net.minecraft.core.SectionPos;
|
import net.minecraft.core.SectionPos;
|
||||||
import net.minecraft.server.level.WorldGenRegion;
|
import net.minecraft.server.level.WorldGenRegion;
|
||||||
import net.minecraft.world.level.ChunkPos;
|
import net.minecraft.world.level.ChunkPos;
|
||||||
|
#if PRE_MC_1_19
|
||||||
import net.minecraft.world.level.StructureFeatureManager;
|
import net.minecraft.world.level.StructureFeatureManager;
|
||||||
|
#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.ChunkStatus;
|
||||||
import net.minecraft.world.level.chunk.ProtoChunk;
|
import net.minecraft.world.level.chunk.ProtoChunk;
|
||||||
|
|||||||
+32
-1
@@ -1,3 +1,22 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
|
||||||
|
* licensed under the GNU LGPL v3 License.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2020-2022 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.lod.common.wrappers.worldGeneration.step;
|
package com.seibel.lod.common.wrappers.worldGeneration.step;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -48,19 +67,31 @@ public final class StepStructureStart {
|
|||||||
chunksToDo.add(chunk);
|
chunksToDo.add(chunk);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if PRE_MC_1_19
|
||||||
if (environment.params.worldGenSettings.generateFeatures()) {
|
if (environment.params.worldGenSettings.generateFeatures()) {
|
||||||
|
#elif POST_MC_1_19
|
||||||
|
if (environment.params.worldGenSettings.generateStructures()) {
|
||||||
|
#endif
|
||||||
for (ChunkAccess chunk : chunksToDo) {
|
for (ChunkAccess chunk : chunksToDo) {
|
||||||
// System.out.println("StepStructureStart: "+chunk.getPos());
|
// System.out.println("StepStructureStart: "+chunk.getPos());
|
||||||
|
#if PRE_MC_1_19
|
||||||
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 POST_MC_1_19
|
||||||
|
environment.params.generator.createStructures(environment.params.registry, environment.params.randomState, tParams.structFeat, chunk, environment.params.structures,
|
||||||
|
environment.params.worldSeed);
|
||||||
|
#endif
|
||||||
|
#if POST_MC_1_18_1
|
||||||
try {
|
try {
|
||||||
tParams.structCheck.onStructureLoad(chunk.getPos(), chunk.getAllStarts());
|
tParams.structCheck.onStructureLoad(chunk.getPos(), chunk.getAllStarts());
|
||||||
} catch (ArrayIndexOutOfBoundsException e) {
|
} catch (ArrayIndexOutOfBoundsException e) {
|
||||||
// There's a rare issue with StructStart where it throws ArrayIndexOutOfBounds
|
// There's a rare issue with StructStart where it throws ArrayIndexOutOfBounds
|
||||||
// This means the structFeat is corrupted (For some reason) and I need to reset it.
|
// This means the structFeat is corrupted (For some reason) and I need to reset it.
|
||||||
// TODO: Figure out in the future why this happens even though I am using new structFeat
|
// TODO: Figure out in the future why this happens even though I am using new structFeat - OLD
|
||||||
|
// TODO: Is this still a problem?
|
||||||
throw new StepStructureStart.StructStartCorruptedException(e);
|
throw new StepStructureStart.StructStartCorruptedException(e);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+26
-2
@@ -1,3 +1,22 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
|
||||||
|
* licensed under the GNU LGPL v3 License.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2020-2022 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.lod.common.wrappers.worldGeneration.step;
|
package com.seibel.lod.common.wrappers.worldGeneration.step;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -39,8 +58,13 @@ public final class StepSurface {
|
|||||||
|
|
||||||
for (ChunkAccess chunk : chunksToDo) {
|
for (ChunkAccess chunk : chunksToDo) {
|
||||||
// System.out.println("StepSurface: "+chunk.getPos());
|
// System.out.println("StepSurface: "+chunk.getPos());
|
||||||
environment.params.generator.buildSurface(worldGenRegion, tParams.structFeat.forWorldGenRegion(worldGenRegion),
|
#if PRE_MC_1_18_1
|
||||||
chunk);
|
environment.params.generator.buildSurfaceAndBedrock(worldGenRegion, chunk);
|
||||||
|
#elif PRE_MC_1_19
|
||||||
|
environment.params.generator.buildSurface(worldGenRegion, tParams.structFeat.forWorldGenRegion(worldGenRegion), chunk);
|
||||||
|
#else
|
||||||
|
environment.params.generator.buildSurface(worldGenRegion, tParams.structFeat.forWorldGenRegion(worldGenRegion), environment.params.randomState, chunk);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
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 field com/mojang/blaze3d/vertex/VertexBuffer vertexCount I
|
||||||
|
accessible field com/mojang/blaze3d/vertex/VertexBuffer id I
|
||||||
|
accessible method net/minecraft/client/renderer/GameRenderer getFov (Lnet/minecraft/client/Camera;FZ)D
|
||||||
|
|
||||||
|
# pre-render setup
|
||||||
|
accessible field net/minecraft/client/renderer/LevelRenderer renderChunks Lit/unimi/dsi/fastutil/objects/ObjectList;
|
||||||
|
accessible class net/minecraft/client/renderer/LevelRenderer$RenderChunkInfo
|
||||||
|
accessible field net/minecraft/client/renderer/LevelRenderer$RenderChunkInfo chunk Lnet/minecraft/client/renderer/chunk/ChunkRenderDispatcher$RenderChunk;
|
||||||
|
|
||||||
|
# used for grabbing vanilla rendered chunks
|
||||||
|
accessible class net/minecraft/client/renderer/LevelRenderer$RenderChunkInfo
|
||||||
|
accessible field net/minecraft/client/renderer/LevelRenderer$RenderChunkInfo chunk Lnet/minecraft/client/renderer/chunk/ChunkRenderDispatcher$RenderChunk;
|
||||||
|
#accessible field net/minecraft/world/entity/Entity blockPosition Lnet/minecraft/core/BlockPos;
|
||||||
|
|
||||||
|
# lighting
|
||||||
|
accessible field net/minecraft/client/renderer/LightTexture lightPixels Lcom/mojang/blaze3d/platform/NativeImage;
|
||||||
|
accessible field net/minecraft/client/renderer/LightTexture lightTexture Lnet/minecraft/client/renderer/texture/DynamicTexture;
|
||||||
|
accessible field net/minecraft/world/level/lighting/LevelLightEngine blockEngine Lnet/minecraft/world/level/lighting/LayerLightEngine;
|
||||||
|
accessible field net/minecraft/world/level/lighting/LevelLightEngine skyEngine Lnet/minecraft/world/level/lighting/LayerLightEngine;
|
||||||
|
|
||||||
|
# world generation
|
||||||
|
accessible method net/minecraft/world/level/levelgen/Heightmap setHeight (III)V
|
||||||
|
accessible field net/minecraft/world/level/biome/Biome generationSettings Lnet/minecraft/world/level/biome/BiomeGenerationSettings;
|
||||||
|
accessible field net/minecraft/world/level/biome/Biome biomeCategory Lnet/minecraft/world/level/biome/Biome$BiomeCategory;
|
||||||
|
#accessible field net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator settings Lnet/minecraft/core/Holder;
|
||||||
|
#accessible method net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator doCreateBiomes (Lnet/minecraft/core/Registry;Lnet/minecraft/world/level/levelgen/blending/Blender;Lnet/minecraft/world/level/StructureFeatureManager;Lnet/minecraft/world/level/chunk/ChunkAccess;)V
|
||||||
|
accessible method net/minecraft/world/level/lighting/LayerLightEngine queueSectionData (JLnet/minecraft/world/level/chunk/DataLayer;Z)V
|
||||||
|
|
||||||
|
# lod generation from save file
|
||||||
|
accessible field net/minecraft/server/level/ChunkMap mainThreadExecutor Lnet/minecraft/util/thread/BlockableEventLoop;
|
||||||
|
accessible method net/minecraft/server/level/ChunkMap readChunk (Lnet/minecraft/world/level/ChunkPos;)Lnet/minecraft/nbt/CompoundTag;
|
||||||
|
|
||||||
|
# grabbing textures
|
||||||
|
accessible field net/minecraft/client/renderer/block/model/BakedQuad sprite Lnet/minecraft/client/renderer/texture/TextureAtlasSprite;
|
||||||
|
accessible field net/minecraft/client/renderer/texture/TextureAtlasSprite framesX [I
|
||||||
|
accessible field net/minecraft/client/renderer/texture/TextureAtlasSprite framesY [I
|
||||||
|
accessible field net/minecraft/client/renderer/texture/TextureAtlasSprite mainImage [Lcom/mojang/blaze3d/platform/NativeImage;
|
||||||
|
|
||||||
|
extendable class com/mojang/math/Matrix4f
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
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 field com/mojang/blaze3d/vertex/VertexBuffer indexCount I
|
||||||
|
accessible field com/mojang/blaze3d/vertex/VertexBuffer vertextBufferId I
|
||||||
|
accessible method net/minecraft/client/renderer/GameRenderer getFov (Lnet/minecraft/client/Camera;FZ)D
|
||||||
|
|
||||||
|
# pre-render setup
|
||||||
|
accessible field net/minecraft/client/renderer/LevelRenderer renderChunks Lit/unimi/dsi/fastutil/objects/ObjectArrayList;
|
||||||
|
accessible class net/minecraft/client/renderer/LevelRenderer$RenderChunkInfo
|
||||||
|
accessible field net/minecraft/client/renderer/LevelRenderer$RenderChunkInfo chunk Lnet/minecraft/client/renderer/chunk/ChunkRenderDispatcher$RenderChunk;
|
||||||
|
|
||||||
|
# used for grabbing vanilla rendered chunks
|
||||||
|
accessible class net/minecraft/client/renderer/LevelRenderer$RenderChunkInfo
|
||||||
|
accessible field net/minecraft/client/renderer/LevelRenderer$RenderChunkInfo chunk Lnet/minecraft/client/renderer/chunk/ChunkRenderDispatcher$RenderChunk;
|
||||||
|
|
||||||
|
# lighting
|
||||||
|
accessible field net/minecraft/client/renderer/LightTexture lightPixels Lcom/mojang/blaze3d/platform/NativeImage;
|
||||||
|
accessible field net/minecraft/client/renderer/LightTexture lightTexture Lnet/minecraft/client/renderer/texture/DynamicTexture;
|
||||||
|
accessible field net/minecraft/world/level/lighting/LevelLightEngine blockEngine Lnet/minecraft/world/level/lighting/LayerLightEngine;
|
||||||
|
accessible field net/minecraft/world/level/lighting/LevelLightEngine skyEngine Lnet/minecraft/world/level/lighting/LayerLightEngine;
|
||||||
|
|
||||||
|
# world generation
|
||||||
|
accessible method net/minecraft/world/level/levelgen/Heightmap setHeight (III)V
|
||||||
|
accessible field net/minecraft/world/level/biome/Biome generationSettings Lnet/minecraft/world/level/biome/BiomeGenerationSettings;
|
||||||
|
accessible field net/minecraft/world/level/biome/Biome biomeCategory Lnet/minecraft/world/level/biome/Biome$BiomeCategory;
|
||||||
|
# accessible field net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator settings Lnet/minecraft/core/Holder;
|
||||||
|
#accessible method net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator doCreateBiomes (Lnet/minecraft/core/Registry;Lnet/minecraft/world/level/levelgen/blending/Blender;Lnet/minecraft/world/level/StructureFeatureManager;Lnet/minecraft/world/level/chunk/ChunkAccess;)V
|
||||||
|
accessible method net/minecraft/world/level/lighting/LayerLightEngine queueSectionData (JLnet/minecraft/world/level/chunk/DataLayer;Z)V
|
||||||
|
|
||||||
|
# lod generation from save file
|
||||||
|
accessible field net/minecraft/server/level/ChunkMap mainThreadExecutor Lnet/minecraft/util/thread/BlockableEventLoop;
|
||||||
|
accessible method net/minecraft/server/level/ChunkMap readChunk (Lnet/minecraft/world/level/ChunkPos;)Lnet/minecraft/nbt/CompoundTag;
|
||||||
|
|
||||||
|
|
||||||
|
# grabbing textures
|
||||||
|
accessible field net/minecraft/client/renderer/texture/TextureAtlasSprite animatedTexture Lnet/minecraft/client/renderer/texture/TextureAtlasSprite$AnimatedTexture;
|
||||||
|
accessible field net/minecraft/client/renderer/texture/TextureAtlasSprite width I
|
||||||
|
accessible field net/minecraft/client/renderer/texture/TextureAtlasSprite height I
|
||||||
|
accessible field net/minecraft/client/renderer/texture/TextureAtlasSprite mainImage [Lcom/mojang/blaze3d/platform/NativeImage;
|
||||||
|
accessible class net/minecraft/client/renderer/texture/TextureAtlasSprite$AnimatedTexture
|
||||||
|
accessible method net/minecraft/client/renderer/texture/TextureAtlasSprite$AnimatedTexture getFrameX (I)I
|
||||||
|
accessible method net/minecraft/client/renderer/texture/TextureAtlasSprite$AnimatedTexture getFrameY (I)I
|
||||||
|
extendable class com/mojang/math/Matrix4f
|
||||||
+2
@@ -1,5 +1,6 @@
|
|||||||
accessWidener v1 named
|
accessWidener v1 named
|
||||||
|
|
||||||
|
|
||||||
# used when determining where to save files to
|
# used when determining where to save files to
|
||||||
accessible field net/minecraft/world/level/storage/DimensionDataStorage dataFolder Ljava/io/File;
|
accessible field net/minecraft/world/level/storage/DimensionDataStorage dataFolder Ljava/io/File;
|
||||||
|
|
||||||
@@ -16,6 +17,7 @@ accessible field net/minecraft/client/renderer/LevelRenderer$RenderChunkInfo chu
|
|||||||
|
|
||||||
# lighting
|
# lighting
|
||||||
accessible field net/minecraft/client/renderer/LightTexture lightPixels Lcom/mojang/blaze3d/platform/NativeImage;
|
accessible field net/minecraft/client/renderer/LightTexture lightPixels Lcom/mojang/blaze3d/platform/NativeImage;
|
||||||
|
accessible field net/minecraft/client/renderer/LightTexture lightTexture Lnet/minecraft/client/renderer/texture/DynamicTexture;
|
||||||
accessible field net/minecraft/world/level/lighting/LevelLightEngine blockEngine Lnet/minecraft/world/level/lighting/LayerLightEngine;
|
accessible field net/minecraft/world/level/lighting/LevelLightEngine blockEngine Lnet/minecraft/world/level/lighting/LayerLightEngine;
|
||||||
accessible field net/minecraft/world/level/lighting/LevelLightEngine skyEngine Lnet/minecraft/world/level/lighting/LayerLightEngine;
|
accessible field net/minecraft/world/level/lighting/LevelLightEngine skyEngine Lnet/minecraft/world/level/lighting/LayerLightEngine;
|
||||||
|
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
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 field com/mojang/blaze3d/vertex/VertexBuffer indexCount I
|
||||||
|
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 renderChunkStorage Ljava/util/concurrent/atomic/AtomicReference;
|
||||||
|
accessible class net/minecraft/client/renderer/LevelRenderer$RenderChunkStorage
|
||||||
|
accessible class net/minecraft/client/renderer/LevelRenderer$RenderChunkInfo
|
||||||
|
accessible field net/minecraft/client/renderer/LevelRenderer$RenderChunkInfo chunk Lnet/minecraft/client/renderer/chunk/ChunkRenderDispatcher$RenderChunk;
|
||||||
|
|
||||||
|
# lighting
|
||||||
|
accessible field net/minecraft/client/renderer/LightTexture lightPixels Lcom/mojang/blaze3d/platform/NativeImage;
|
||||||
|
accessible field net/minecraft/client/renderer/LightTexture lightTexture Lnet/minecraft/client/renderer/texture/DynamicTexture;
|
||||||
|
accessible field net/minecraft/world/level/lighting/LevelLightEngine blockEngine Lnet/minecraft/world/level/lighting/LayerLightEngine;
|
||||||
|
accessible field net/minecraft/world/level/lighting/LevelLightEngine skyEngine Lnet/minecraft/world/level/lighting/LayerLightEngine;
|
||||||
|
|
||||||
|
# world generation
|
||||||
|
accessible method net/minecraft/world/level/levelgen/Heightmap setHeight (III)V
|
||||||
|
accessible field net/minecraft/world/level/biome/Biome generationSettings Lnet/minecraft/world/level/biome/BiomeGenerationSettings;
|
||||||
|
# accessible field net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator settings Lnet/minecraft/core/Holder;
|
||||||
|
accessible method net/minecraft/world/level/lighting/LayerLightEngine queueSectionData (JLnet/minecraft/world/level/chunk/DataLayer;Z)V
|
||||||
|
accessible method net/minecraft/server/level/ChunkMap readChunk (Lnet/minecraft/world/level/ChunkPos;)Ljava/util/concurrent/CompletableFuture;
|
||||||
|
|
||||||
|
|
||||||
|
# lod generation from save file
|
||||||
|
accessible field net/minecraft/server/level/ChunkMap mainThreadExecutor Lnet/minecraft/util/thread/BlockableEventLoop;
|
||||||
|
|
||||||
|
|
||||||
|
# grabbing textures
|
||||||
|
accessible field net/minecraft/client/renderer/texture/TextureAtlasSprite animatedTexture Lnet/minecraft/client/renderer/texture/TextureAtlasSprite$AnimatedTexture;
|
||||||
|
accessible field net/minecraft/client/renderer/texture/TextureAtlasSprite width I
|
||||||
|
accessible field net/minecraft/client/renderer/texture/TextureAtlasSprite height I
|
||||||
|
accessible field net/minecraft/client/renderer/texture/TextureAtlasSprite mainImage [Lcom/mojang/blaze3d/platform/NativeImage;
|
||||||
|
accessible class net/minecraft/client/renderer/texture/TextureAtlasSprite$AnimatedTexture
|
||||||
|
accessible method net/minecraft/client/renderer/texture/TextureAtlasSprite$AnimatedTexture getFrameX (I)I
|
||||||
|
accessible method net/minecraft/client/renderer/texture/TextureAtlasSprite$AnimatedTexture getFrameY (I)I
|
||||||
|
extendable class com/mojang/math/Matrix4f
|
||||||
|
|
||||||
|
# hacky stuff
|
||||||
|
accessible field net/minecraft/util/ThreadingDetector lock Ljava/util/concurrent/Semaphore;
|
||||||
|
mutable field net/minecraft/util/ThreadingDetector lock Ljava/util/concurrent/Semaphore;
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"accessWidener": "lod.accesswidener"
|
||||||
|
}
|
||||||
-1
Submodule core deleted from 6cd0281d0e
Submodule
+1
Submodule coreSubProjects added at c3c170d07a
+66
-64
@@ -1,27 +1,25 @@
|
|||||||
plugins {
|
version = rootProject.versionStr
|
||||||
id "com.github.johnrengelman.shadow" version "7.1.0"
|
|
||||||
}
|
|
||||||
|
|
||||||
version = rootProject.mod_version+"-"+rootProject.minecraft_version+"-"+new Date().format("yyyy_MM_dd_HH_mm")
|
|
||||||
|
|
||||||
loom {
|
|
||||||
accessWidenerPath.set(project(":common").file("src/main/resources/lod.accesswidener"))
|
|
||||||
}
|
|
||||||
|
|
||||||
architectury {
|
architectury {
|
||||||
platformSetupLoomIde()
|
platformSetupLoomIde()
|
||||||
fabric()
|
fabric()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
loom {
|
||||||
|
accessWidenerPath = project(":common").loom.accessWidenerPath
|
||||||
|
}
|
||||||
|
|
||||||
configurations {
|
configurations {
|
||||||
|
common
|
||||||
|
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
|
||||||
developmentFabric.extendsFrom common
|
developmentFabric.extendsFrom common
|
||||||
}
|
|
||||||
|
|
||||||
repositories {
|
// The addModJar basically embeds the mod to the built jar
|
||||||
// Required for ModMenu
|
addModJar
|
||||||
maven { url "https://maven.terraformersmc.com/" }
|
include.extendsFrom addModJar
|
||||||
|
modImplementation.extendsFrom addModJar
|
||||||
}
|
}
|
||||||
|
|
||||||
def addMod(path, enabled) {
|
def addMod(path, enabled) {
|
||||||
@@ -35,21 +33,37 @@ dependencies {
|
|||||||
// Fabric loader
|
// Fabric loader
|
||||||
modImplementation "net.fabricmc:fabric-loader:${rootProject.fabric_loader_version}"
|
modImplementation "net.fabricmc:fabric-loader:${rootProject.fabric_loader_version}"
|
||||||
|
|
||||||
|
// Architectury API
|
||||||
|
if (minecraft_version == "1.16.5") {
|
||||||
|
addModJar("me.shedaniel:architectury-fabric:${rootProject.architectury_version}")
|
||||||
|
} else {
|
||||||
|
addModJar("dev.architectury:architectury-fabric:${rootProject.architectury_version}")
|
||||||
|
}
|
||||||
|
|
||||||
// Fabric API
|
// Fabric API
|
||||||
modApi "net.fabricmc.fabric-api:fabric-api:${rootProject.fabric_api_version}"
|
addModJar(fabricApi.module("fabric-lifecycle-events-v1", rootProject.fabric_api_version))
|
||||||
|
addModJar(fabricApi.module("fabric-key-binding-api-v1", rootProject.fabric_api_version))
|
||||||
|
addModJar(fabricApi.module("fabric-resource-loader-v0", rootProject.fabric_api_version))
|
||||||
|
addModJar(fabricApi.module("fabric-rendering-v1", rootProject.fabric_api_version)) // TODO: Remove this as it is only needed in 1 line (FabricClientProxy)
|
||||||
|
addModJar(fabricApi.module("fabric-api-base", rootProject.fabric_api_version))
|
||||||
|
|
||||||
// Mod Menu
|
// Mod Menu
|
||||||
modImplementation("com.terraformersmc:modmenu:${rootProject.modmenu_version}") {
|
modImplementation("com.terraformersmc:modmenu:${rootProject.modmenu_version}")
|
||||||
exclude(group: "net.fabricmc.fabric-api")
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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)
|
||||||
|
|
||||||
|
// Phosphor
|
||||||
|
addMod("curse.maven:phosphor-372124:${rootProject.phosphor_version_fabric}", rootProject.enable_phosphor)
|
||||||
|
|
||||||
// Sodium
|
// Sodium
|
||||||
addMod("curse.maven:sodium-394468:${rootProject.sodium_version}", rootProject.enable_sodium)
|
addMod("maven.modrinth:sodium:${rootProject.sodium_version}", rootProject.enable_sodium)
|
||||||
implementation "org.joml:joml:1.10.2"
|
// if (rootProject.enable_sodium != "0") {
|
||||||
|
// implementation "org.joml:joml:1.10.2"
|
||||||
|
// modImplementation(fabricApi.module("fabric-rendering-data-attachment-v1", rootProject.fabric_api_version))
|
||||||
|
// modImplementation(fabricApi.module("fabric-rendering-fluids-v1", rootProject.fabric_api_version))
|
||||||
|
// }
|
||||||
|
|
||||||
// Lithium
|
// Lithium
|
||||||
addMod("maven.modrinth:lithium:${rootProject.lithium_version}", rootProject.enable_lithium)
|
addMod("maven.modrinth:lithium:${rootProject.lithium_version}", rootProject.enable_lithium)
|
||||||
|
|
||||||
@@ -59,6 +73,9 @@ dependencies {
|
|||||||
// BCLib
|
// BCLib
|
||||||
addMod("com.github.paulevsGitch:BCLib:${rootProject.bclib_version}", rootProject.enable_bclib)
|
addMod("com.github.paulevsGitch:BCLib:${rootProject.bclib_version}", rootProject.enable_bclib)
|
||||||
|
|
||||||
|
// Canvas
|
||||||
|
addMod("io.vram:canvas-fabric-${project.canvas_version}", rootProject.enable_canvas)
|
||||||
|
|
||||||
// Immersive Portals
|
// Immersive Portals
|
||||||
/*
|
/*
|
||||||
modImplementation("com.github.qouteall.ImmersivePortalsMod:build:${rootProject.immersive_portals_version}") {
|
modImplementation("com.github.qouteall.ImmersivePortalsMod:build:${rootProject.immersive_portals_version}") {
|
||||||
@@ -73,71 +90,56 @@ dependencies {
|
|||||||
exclude(group: "net.fabricmc.fabric-api")
|
exclude(group: "net.fabricmc.fabric-api")
|
||||||
transitive(false)
|
transitive(false)
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Toml
|
|
||||||
shadowMe("com.electronwill.night-config:toml:${rootProject.toml_version}") {}
|
|
||||||
|
|
||||||
common(project(path: ":common", configuration: "namedElements")) { transitive false }
|
common(project(path: ":common", configuration: "namedElements")) { transitive false }
|
||||||
shadowMe(project(path: ":common", configuration: "transformProductionFabric")) { transitive false }
|
shadowCommon(project(path: ":common", configuration: "transformProductionFabric")) { transitive false }
|
||||||
|
}
|
||||||
|
|
||||||
|
shadowJar {
|
||||||
|
exclude "architectury.common.json"
|
||||||
|
|
||||||
|
configurations = [project.configurations.shadowCommon, project.configurations.shadowMe, project.configurations.customModule]
|
||||||
|
|
||||||
// Compression
|
// Compression
|
||||||
common 'org.tukaani:xz:1.9'
|
relocate 'org.tukaani', 'distanthorizons.libraries.tukaani'
|
||||||
common 'org.apache.commons:commons-compress:1.21'
|
relocate 'org.apache.commons.compress', 'distanthorizons.libraries.apache.commons.compress'
|
||||||
shadowMe 'org.tukaani:xz:1.9'
|
|
||||||
shadowMe 'org.apache.commons:commons-compress:1.21'
|
// NightConfig (includes Toml & Json)
|
||||||
|
relocate 'com.electronwill.nightconfig', 'distanthorizons.libraries.electronwill.nightconfig'
|
||||||
|
|
||||||
|
// Theming
|
||||||
|
relocate 'com.formdev.flatlaf', 'distanthorizons.libraries.formdev.flatlaf'
|
||||||
|
|
||||||
|
// SVG
|
||||||
|
relocate 'com.kitfox.svg', 'distanthorizons.libraries.kitfox.svg'
|
||||||
|
|
||||||
|
classifier "dev-shadow"
|
||||||
|
mergeServiceFiles()
|
||||||
}
|
}
|
||||||
|
|
||||||
// This method copies the access wideners from the common project to the fabric project. And it was generated by Github Copilot
|
remapJar {
|
||||||
task copyAccessWidener(type: Copy) {
|
injectAccessWidener = true
|
||||||
from project(":common").file("src/main/resources/lod.accesswidener")
|
input.set shadowJar.archiveFile
|
||||||
into file("src/generated/resources")
|
dependsOn shadowJar
|
||||||
}
|
classifier null
|
||||||
|
|
||||||
task copyCoreResources(type: Copy) {
|
|
||||||
from fileTree(project(":core").file("src/main/resources"))
|
|
||||||
into file("build/resources/main")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
task deleteResources(type: Delete) {
|
task deleteResources(type: Delete) {
|
||||||
delete file("build/resources/main")
|
delete file("build/resources/main")
|
||||||
}
|
}
|
||||||
|
|
||||||
task copyCommonResources(type: Copy) {
|
processResources {
|
||||||
from fileTree(project(":common").file("src/main/resources"))
|
dependsOn(copyCoreResources)
|
||||||
into file("build/resources/main")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
runClient {
|
runClient {
|
||||||
dependsOn(copyCoreResources)
|
dependsOn(copyCoreResources)
|
||||||
dependsOn(copyCommonResources)
|
|
||||||
jvmArgs "-XX:-OmitStackTraceInFastThrow"
|
jvmArgs "-XX:-OmitStackTraceInFastThrow"
|
||||||
finalizedBy(deleteResources)
|
finalizedBy(deleteResources)
|
||||||
}
|
}
|
||||||
|
|
||||||
processResources {
|
|
||||||
dependsOn(copyAccessWidener)
|
|
||||||
}
|
|
||||||
|
|
||||||
shadowJar {
|
|
||||||
configurations = [project.configurations.shadowMe]
|
|
||||||
relocate 'org.tukaani', 'shaded.tukaani'
|
|
||||||
relocate 'org.apache.commons.compress', 'shaded.apache.commons.compress'
|
|
||||||
relocate 'com.electronwill.nightconfig', 'shaded.electronwill.nightconfig'
|
|
||||||
|
|
||||||
relocate 'com.seibel.lod.common', 'fabric.com.seibel.lod.common'
|
|
||||||
|
|
||||||
classifier "dev-shadow"
|
|
||||||
}
|
|
||||||
|
|
||||||
remapJar {
|
|
||||||
input.set shadowJar.archiveFile
|
|
||||||
dependsOn shadowJar
|
|
||||||
classifier null
|
|
||||||
}
|
|
||||||
|
|
||||||
jar {
|
jar {
|
||||||
classifier "dev"
|
classifier "dev"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
package com.seibel.lod;
|
||||||
|
|
||||||
|
import com.seibel.lod.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();
|
||||||
|
|
||||||
|
server_proxy = new FabricServerProxy(false);
|
||||||
|
server_proxy.registerEvents();
|
||||||
|
client_proxy = new FabricClientProxy();
|
||||||
|
client_proxy.registerEvents();
|
||||||
|
|
||||||
|
ClientLifecycleEvents.CLIENT_STARTED.register((mc) -> FabricMain.postInit());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,174 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
|
||||||
|
* licensed under the GNU LGPL v3 License.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2020-2022 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.lod;
|
||||||
|
|
||||||
|
import com.seibel.lod.common.wrappers.McObjectConverter;
|
||||||
|
import com.seibel.lod.common.wrappers.world.ClientLevelWrapper;
|
||||||
|
import com.seibel.lod.core.api.internal.ClientApi;
|
||||||
|
import com.seibel.lod.core.config.Config;
|
||||||
|
import com.mojang.blaze3d.platform.InputConstants;
|
||||||
|
import com.seibel.lod.common.wrappers.chunk.ChunkWrapper;
|
||||||
|
|
||||||
|
import com.seibel.lod.core.dependencyInjection.ModAccessorInjector;
|
||||||
|
import com.seibel.lod.core.logging.DhLoggerBuilder;
|
||||||
|
import com.seibel.lod.core.wrapperInterfaces.modAccessor.ISodiumAccessor;
|
||||||
|
import com.seibel.lod.wrappers.modAccessor.SodiumAccessor;
|
||||||
|
import net.fabricmc.api.EnvType;
|
||||||
|
import net.fabricmc.api.Environment;
|
||||||
|
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientChunkEvents;
|
||||||
|
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
|
||||||
|
import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderEvents;
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.client.gui.screens.TitleScreen;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.lwjgl.glfw.GLFW;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This handles all events sent to the client,
|
||||||
|
* and is the starting point for most of the mod.
|
||||||
|
*
|
||||||
|
* @author coolGi
|
||||||
|
* @author Ran
|
||||||
|
* @version 11-23-2021
|
||||||
|
*/
|
||||||
|
@Environment(EnvType.CLIENT)
|
||||||
|
public class FabricClientProxy
|
||||||
|
{
|
||||||
|
private final ClientApi clientApi = ClientApi.INSTANCE;
|
||||||
|
private static final Logger LOGGER = DhLoggerBuilder.getLogger("FabricClientProxy");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers Fabric Events
|
||||||
|
* @author Ran
|
||||||
|
*/
|
||||||
|
public void registerEvents() {
|
||||||
|
LOGGER.info("Registering Fabric Client Events");
|
||||||
|
|
||||||
|
|
||||||
|
/* Register the mod needed event callbacks */
|
||||||
|
|
||||||
|
// ClientTickEvent
|
||||||
|
ClientTickEvents.START_CLIENT_TICK.register((client) -> {
|
||||||
|
//LOGGER.info("ClientTickEvent.START_CLIENT_TICK");
|
||||||
|
ClientApi.INSTANCE.clientTickEvent();
|
||||||
|
});
|
||||||
|
|
||||||
|
// ClientLevelLoadEvent - Done in MixinClientPacketListener
|
||||||
|
// ClientLevelUnloadEvent - Done in MixinClientPacketListener
|
||||||
|
|
||||||
|
// ClientChunkLoadEvent
|
||||||
|
// TODO: Is using setClientLightReady one still better?
|
||||||
|
//#if PRE_MC_1_18_1 // in 1.18+, we use mixin hook in setClientLightReady(true)
|
||||||
|
ClientChunkEvents.CHUNK_LOAD.register((level, chunk) ->
|
||||||
|
{
|
||||||
|
ClientLevelWrapper wrappedLevel = ClientLevelWrapper.getWrapper(level);
|
||||||
|
ClientApi.INSTANCE.clientChunkLoadEvent(
|
||||||
|
new ChunkWrapper(chunk, level, wrappedLevel),
|
||||||
|
wrappedLevel
|
||||||
|
);
|
||||||
|
});
|
||||||
|
//#endif
|
||||||
|
// ClientChunkSaveEvent
|
||||||
|
ClientChunkEvents.CHUNK_UNLOAD.register((level, chunk) ->
|
||||||
|
{
|
||||||
|
ClientLevelWrapper wrappedLevel = ClientLevelWrapper.getWrapper(level);
|
||||||
|
ClientApi.INSTANCE.clientChunkSaveEvent(
|
||||||
|
new ChunkWrapper(chunk, level, wrappedLevel),
|
||||||
|
wrappedLevel
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
// RendererStartupEvent - Done in MixinGameRenderer
|
||||||
|
// RendererShutdownEvent - Done in MixinGameRenderer
|
||||||
|
|
||||||
|
SodiumAccessor sodiumAccessor = (SodiumAccessor) ModAccessorInjector.INSTANCE.get(ISodiumAccessor.class);
|
||||||
|
|
||||||
|
// ClientRenderLevelTerrainEvent
|
||||||
|
WorldRenderEvents.AFTER_SETUP.register((renderContext) -> {
|
||||||
|
if (sodiumAccessor != null) {
|
||||||
|
sodiumAccessor.levelWrapper = ClientLevelWrapper.getWrapper(renderContext.world());
|
||||||
|
sodiumAccessor.mcModelViewMatrix = McObjectConverter.Convert(renderContext.matrixStack().last().pose());
|
||||||
|
sodiumAccessor.mcProjectionMatrix = McObjectConverter.Convert(renderContext.projectionMatrix());
|
||||||
|
sodiumAccessor.partialTicks = renderContext.tickDelta();
|
||||||
|
} else {
|
||||||
|
clientApi.renderLods(ClientLevelWrapper.getWrapper(renderContext.world()),
|
||||||
|
McObjectConverter.Convert(renderContext.matrixStack().last().pose()),
|
||||||
|
McObjectConverter.Convert(renderContext.projectionMatrix()),
|
||||||
|
renderContext.tickDelta());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// Debug keyboard event
|
||||||
|
// FIXME: Use better hooks so it doesn't trigger even in text boxes
|
||||||
|
ClientTickEvents.END_CLIENT_TICK.register(client -> {
|
||||||
|
if (client.player != null && isValidTime()) onKeyInput();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isValidTime() {
|
||||||
|
return !(Minecraft.getInstance().screen instanceof TitleScreen);
|
||||||
|
}
|
||||||
|
|
||||||
|
// public void blockChangeEvent(LevelAccessor world, BlockPos pos) {
|
||||||
|
// if (!isValidTime()) return;
|
||||||
|
// IChunkWrapper chunk = new ChunkWrapper(world.getChunk(pos), world);
|
||||||
|
// DimensionTypeWrapper dimType = DimensionTypeWrapper.getDimensionTypeWrapper(world.dimensionType());
|
||||||
|
//
|
||||||
|
// // recreate the LOD where the blocks were changed
|
||||||
|
// // TODO: serverApi.blockChangeEvent(chunk, dimType);
|
||||||
|
// }
|
||||||
|
|
||||||
|
private static final int[] KEY_TO_CHECK_FOR = {GLFW.GLFW_KEY_F6, GLFW.GLFW_KEY_F8};
|
||||||
|
|
||||||
|
HashSet<Integer> previousKeyDown = new HashSet<>();
|
||||||
|
|
||||||
|
public void onKeyInput() {
|
||||||
|
if (Config.Client.Advanced.Debugging.enableDebugKeybindings.get())
|
||||||
|
{
|
||||||
|
HashSet<Integer> currentKeyDown = new HashSet<Integer>();
|
||||||
|
|
||||||
|
// Note: Minecraft's InputConstants is same as GLFW Key values
|
||||||
|
//TODO: Use mixin to hook directly into the GLFW Keyboard event in minecraft KeyboardHandler
|
||||||
|
// Check all keys we need
|
||||||
|
for (int i = GLFW.GLFW_KEY_A; i <= GLFW.GLFW_KEY_Z; i++) {
|
||||||
|
if (InputConstants.isKeyDown(Minecraft.getInstance().getWindow().getWindow(), i)) {
|
||||||
|
currentKeyDown.add(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int i : KEY_TO_CHECK_FOR) {
|
||||||
|
if (InputConstants.isKeyDown(Minecraft.getInstance().getWindow().getWindow(), i)) {
|
||||||
|
currentKeyDown.add(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Diff and trigger events
|
||||||
|
for (int c : currentKeyDown) {
|
||||||
|
if (!previousKeyDown.contains(c)) {
|
||||||
|
ClientApi.INSTANCE.keyPressedEvent(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Update the set
|
||||||
|
previousKeyDown = currentKeyDown;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
package com.seibel.lod;
|
||||||
|
|
||||||
|
import com.seibel.lod.common.wrappers.DependencySetup;
|
||||||
|
import com.seibel.lod.common.wrappers.minecraft.MinecraftDedicatedServerWrapper;
|
||||||
|
import com.seibel.lod.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();
|
||||||
|
|
||||||
|
server_proxy = new FabricServerProxy(true);
|
||||||
|
server_proxy.registerEvents();
|
||||||
|
|
||||||
|
ServerLifecycleEvents.SERVER_STARTING.register((server) -> {
|
||||||
|
if (hasPostSetupDone) return;
|
||||||
|
hasPostSetupDone = true;
|
||||||
|
LodUtil.assertTrue(server instanceof DedicatedServer);
|
||||||
|
MinecraftDedicatedServerWrapper.INSTANCE.dedicatedServer = (DedicatedServer) server;
|
||||||
|
FabricMain.postInit();
|
||||||
|
LOGGER.info("Dedicated server inited at {}", server.getServerDirectory());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,94 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
|
||||||
|
* licensed under the GNU LGPL v3 License.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2020-2022 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.lod;
|
||||||
|
|
||||||
|
import com.seibel.lod.api.methods.events.abstractEvents.DhApiAfterDhInitEvent;
|
||||||
|
import com.seibel.lod.api.methods.events.abstractEvents.DhApiBeforeDhInitEvent;
|
||||||
|
import com.seibel.lod.common.LodCommonMain;
|
||||||
|
import com.seibel.lod.core.ModInfo;
|
||||||
|
import com.seibel.lod.core.config.Config;
|
||||||
|
import com.seibel.lod.core.DependencyInjection.ApiEventInjector;
|
||||||
|
import com.seibel.lod.core.dependencyInjection.ModAccessorInjector;
|
||||||
|
import com.seibel.lod.core.dependencyInjection.SingletonInjector;
|
||||||
|
import com.seibel.lod.core.logging.DhLoggerBuilder;
|
||||||
|
import com.seibel.lod.core.wrapperInterfaces.modAccessor.*;
|
||||||
|
import com.seibel.lod.wrappers.modAccessor.BCLibAccessor;
|
||||||
|
import com.seibel.lod.wrappers.modAccessor.OptifineAccessor;
|
||||||
|
import com.seibel.lod.wrappers.modAccessor.SodiumAccessor;
|
||||||
|
import com.seibel.lod.wrappers.modAccessor.StarlightAccessor;
|
||||||
|
import com.seibel.lod.wrappers.FabricDependencySetup;
|
||||||
|
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize and setup the Mod. <br>
|
||||||
|
* If you are looking for the real start of the mod
|
||||||
|
* check out the ClientProxy.
|
||||||
|
*
|
||||||
|
* @author coolGi
|
||||||
|
* @author Ran
|
||||||
|
* @version 9-2-2022
|
||||||
|
*/
|
||||||
|
public class FabricMain
|
||||||
|
{
|
||||||
|
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
|
||||||
|
|
||||||
|
public static void postInit() {
|
||||||
|
LOGGER.info("Post-Initializing Mod");
|
||||||
|
FabricDependencySetup.runDelayedSetup();
|
||||||
|
|
||||||
|
if (Config.Client.Graphics.FogQuality.disableVanillaFog.get() && SingletonInjector.INSTANCE.get(IModChecker.class).isModLoaded("bclib"))
|
||||||
|
ModAccessorInjector.INSTANCE.get(IBCLibAccessor.class).setRenderCustomFog(false); // Remove BCLib's fog
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
if (SingletonInjector.INSTANCE.get(IModChecker.class).isModLoaded("sodium")) {
|
||||||
|
ModAccessorInjector.INSTANCE.bind(ISodiumAccessor.class, new SodiumAccessor());
|
||||||
|
}
|
||||||
|
if (SingletonInjector.INSTANCE.get(IModChecker.class).isModLoaded("starlight")) {
|
||||||
|
ModAccessorInjector.INSTANCE.bind(IStarlightAccessor.class, new StarlightAccessor());
|
||||||
|
}
|
||||||
|
if (SingletonInjector.INSTANCE.get(IModChecker.class).isModLoaded("optifine")) {
|
||||||
|
ModAccessorInjector.INSTANCE.bind(IOptifineAccessor.class, new OptifineAccessor());
|
||||||
|
}
|
||||||
|
if (SingletonInjector.INSTANCE.get(IModChecker.class).isModLoaded("bclib")) {
|
||||||
|
ModAccessorInjector.INSTANCE.bind(IBCLibAccessor.class, new BCLibAccessor());
|
||||||
|
}
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,115 @@
|
|||||||
|
package com.seibel.lod;
|
||||||
|
|
||||||
|
import com.seibel.lod.common.networking.Networking;
|
||||||
|
import com.seibel.lod.common.wrappers.chunk.ChunkWrapper;
|
||||||
|
import com.seibel.lod.common.wrappers.world.ClientLevelWrapper;
|
||||||
|
import com.seibel.lod.common.wrappers.world.ServerLevelWrapper;
|
||||||
|
import com.seibel.lod.common.wrappers.worldGeneration.BatchGenerationEnvironment;
|
||||||
|
import com.seibel.lod.core.api.internal.ServerApi;
|
||||||
|
import com.seibel.lod.core.logging.DhLoggerBuilder;
|
||||||
|
import com.seibel.lod.core.wrapperInterfaces.world.ILevelWrapper;
|
||||||
|
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerChunkEvents;
|
||||||
|
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents;
|
||||||
|
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents;
|
||||||
|
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerWorldEvents;
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.client.gui.screens.TitleScreen;
|
||||||
|
import net.minecraft.client.multiplayer.ClientLevel;
|
||||||
|
import net.minecraft.network.FriendlyByteBuf;
|
||||||
|
import net.minecraft.server.MinecraftServer;
|
||||||
|
import net.minecraft.server.level.ServerLevel;
|
||||||
|
import net.minecraft.server.level.ServerPlayer;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This handles all events sent to the server,
|
||||||
|
* and is the starting point for most of the mod.
|
||||||
|
*
|
||||||
|
* @author Ran
|
||||||
|
* @author Tomlee
|
||||||
|
* @version 5-11-2022
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class FabricServerProxy {
|
||||||
|
private final ServerApi serverApi = ServerApi.INSTANCE;
|
||||||
|
private static final Logger LOGGER = DhLoggerBuilder.getLogger("FabricServerProxy");
|
||||||
|
private final boolean isDedicated;
|
||||||
|
public static Supplier<Boolean> isGenerationThreadChecker = null;
|
||||||
|
|
||||||
|
public FabricServerProxy(boolean isDedicated) {
|
||||||
|
this.isDedicated = isDedicated;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isValidTime() {
|
||||||
|
if (isDedicated) return true;
|
||||||
|
|
||||||
|
//FIXME: This may cause init issue...
|
||||||
|
return !(Minecraft.getInstance().screen instanceof TitleScreen);
|
||||||
|
}
|
||||||
|
private ClientLevelWrapper getLevelWrapper(ClientLevel level) {
|
||||||
|
return ClientLevelWrapper.getWrapper(level);
|
||||||
|
}
|
||||||
|
private ServerLevelWrapper getLevelWrapper(ServerLevel level) {
|
||||||
|
return ServerLevelWrapper.getWrapper(level);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Registers Fabric Events
|
||||||
|
* @author Ran, Tomlee
|
||||||
|
*/
|
||||||
|
public void registerEvents() {
|
||||||
|
LOGGER.info("Registering Fabric Server Events");
|
||||||
|
isGenerationThreadChecker = BatchGenerationEnvironment::isCurrentThreadDistantGeneratorThread;
|
||||||
|
|
||||||
|
/* Register the mod needed event callbacks */
|
||||||
|
|
||||||
|
// TEST EVENT
|
||||||
|
//ServerTickEvents.END_SERVER_TICK.register(this::tester);
|
||||||
|
|
||||||
|
// ServerTickEvent
|
||||||
|
ServerTickEvents.END_SERVER_TICK.register((server) -> serverApi.serverTickEvent());
|
||||||
|
|
||||||
|
// ServerWorldLoadEvent
|
||||||
|
//TODO: Check if both of this use the correct timed events. (i.e. is it 'ed' or 'ing' one?)
|
||||||
|
ServerLifecycleEvents.SERVER_STARTING.register((server) -> {
|
||||||
|
if (isValidTime()) ServerApi.INSTANCE.serverWorldLoadEvent(isDedicated);
|
||||||
|
});
|
||||||
|
// ServerWorldUnloadEvent
|
||||||
|
ServerLifecycleEvents.SERVER_STOPPED.register((server) -> {
|
||||||
|
if (isValidTime()) ServerApi.INSTANCE.serverWorldUnloadEvent();
|
||||||
|
});
|
||||||
|
|
||||||
|
// ServerLevelLoadEvent
|
||||||
|
ServerWorldEvents.LOAD.register((server, level)
|
||||||
|
-> {
|
||||||
|
if (isValidTime()) ServerApi.INSTANCE.serverLevelLoadEvent(getLevelWrapper(level));
|
||||||
|
});
|
||||||
|
// ServerLevelUnloadEvent
|
||||||
|
ServerWorldEvents.UNLOAD.register((server, level)
|
||||||
|
-> {
|
||||||
|
if (isValidTime()) ServerApi.INSTANCE.serverLevelUnloadEvent(getLevelWrapper(level));
|
||||||
|
});
|
||||||
|
|
||||||
|
// ServerChunkLoadEvent
|
||||||
|
ServerChunkEvents.CHUNK_LOAD.register((server, chunk)
|
||||||
|
-> {
|
||||||
|
ILevelWrapper level = getLevelWrapper((ServerLevel) chunk.getLevel());
|
||||||
|
if (isValidTime()) ServerApi.INSTANCE.serverChunkLoadEvent(
|
||||||
|
new ChunkWrapper(chunk, chunk.getLevel(), level),
|
||||||
|
level);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
// ServerChunkSaveEvent - Done in MixinChunkMap
|
||||||
|
}
|
||||||
|
|
||||||
|
// This just exists here for testing purposes, it'll be removed in the future
|
||||||
|
public void tester(MinecraftServer server) {
|
||||||
|
for (ServerPlayer player : server.getPlayerList().getPlayers()) {
|
||||||
|
FriendlyByteBuf payload = Networking.createNew();
|
||||||
|
payload.writeInt(1);
|
||||||
|
System.out.println("Sending int 1");
|
||||||
|
Networking.send(player, payload);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,194 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of the Distant Horizon mod (formerly the LOD Mod),
|
|
||||||
* licensed under the GNU GPL v3 License.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2020 James Seibel
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU 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 General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.seibel.lod.fabric;
|
|
||||||
|
|
||||||
import com.seibel.lod.common.wrappers.worldGeneration.BatchGenerationEnvironment;
|
|
||||||
import com.seibel.lod.core.api.ClientApi;
|
|
||||||
import com.seibel.lod.core.api.EventApi;
|
|
||||||
import com.seibel.lod.core.handlers.dependencyInjection.SingletonHandler;
|
|
||||||
import com.mojang.blaze3d.platform.InputConstants;
|
|
||||||
import com.seibel.lod.common.wrappers.chunk.ChunkWrapper;
|
|
||||||
import com.seibel.lod.common.wrappers.world.DimensionTypeWrapper;
|
|
||||||
import com.seibel.lod.common.wrappers.world.WorldWrapper;
|
|
||||||
import com.seibel.lod.core.wrapperInterfaces.chunk.IChunkWrapper;
|
|
||||||
import com.seibel.lod.core.wrapperInterfaces.config.ILodConfigWrapperSingleton;
|
|
||||||
|
|
||||||
import com.seibel.lod.fabric.mixins.MixinUtilBackgroudThread;
|
|
||||||
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
|
|
||||||
import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper;
|
|
||||||
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents;
|
|
||||||
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerWorldEvents;
|
|
||||||
import net.minecraft.client.KeyMapping;
|
|
||||||
import net.minecraft.client.Minecraft;
|
|
||||||
import net.minecraft.core.BlockPos;
|
|
||||||
import net.minecraft.server.MinecraftServer;
|
|
||||||
import net.minecraft.world.level.Level;
|
|
||||||
import net.minecraft.world.level.LevelAccessor;
|
|
||||||
import net.minecraft.world.level.chunk.LevelChunk;
|
|
||||||
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.function.Supplier;
|
|
||||||
|
|
||||||
import org.lwjgl.glfw.GLFW;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This handles all events sent to the client,
|
|
||||||
* and is the starting point for most of the mod.
|
|
||||||
*
|
|
||||||
* @author coolGi2007
|
|
||||||
* @author Ran
|
|
||||||
* @version 11-23-2021
|
|
||||||
*/
|
|
||||||
public class ClientProxy
|
|
||||||
{
|
|
||||||
private final EventApi eventApi = EventApi.INSTANCE;
|
|
||||||
private final ClientApi clientApi = ClientApi.INSTANCE;
|
|
||||||
|
|
||||||
public static Supplier<Boolean> isGenerationThreadChecker = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Registers Fabric Events
|
|
||||||
* @author Ran
|
|
||||||
*/
|
|
||||||
public void registerEvents() {
|
|
||||||
/* Registor the mod accessor*/
|
|
||||||
|
|
||||||
/* World Events */
|
|
||||||
//ServerTickEvents.START_SERVER_TICK.register(this::serverTickEvent);
|
|
||||||
ServerTickEvents.END_SERVER_TICK.register(this::serverTickEvent);
|
|
||||||
|
|
||||||
/* World Events */
|
|
||||||
//ServerChunkEvents.CHUNK_LOAD.register(this::chunkLoadEvent);
|
|
||||||
//ClientChunkEvents.CHUNK_LOAD.register(this::chunkLoadEvent);
|
|
||||||
|
|
||||||
/* World Events */
|
|
||||||
ServerWorldEvents.LOAD.register((server, level) -> this.worldLoadEvent(level));
|
|
||||||
ServerWorldEvents.UNLOAD.register((server, level) -> this.worldUnloadEvent(level));
|
|
||||||
|
|
||||||
/* The Client World Events are in the mixins
|
|
||||||
Client world load event is in MixinClientLevel
|
|
||||||
Client world unload event is in MixinMinecraft */
|
|
||||||
/* The save events are in MixinServerLevel */
|
|
||||||
|
|
||||||
/* Keyboard Events */
|
|
||||||
ClientTickEvents.END_CLIENT_TICK.register(client -> {
|
|
||||||
if (client.player != null) onKeyInput();
|
|
||||||
});
|
|
||||||
isGenerationThreadChecker = BatchGenerationEnvironment::isCurrentThreadDistantGeneratorThread;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void serverTickEvent(MinecraftServer server)
|
|
||||||
{
|
|
||||||
eventApi.serverTickEvent();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void chunkLoadEvent(LevelAccessor level, LevelChunk chunk)
|
|
||||||
{
|
|
||||||
clientApi.clientChunkLoadEvent(new ChunkWrapper(chunk, level),
|
|
||||||
WorldWrapper.getWorldWrapper(level));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void worldSaveEvent()
|
|
||||||
{
|
|
||||||
eventApi.worldSaveEvent();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** This is also called when a new dimension loads */
|
|
||||||
public void worldLoadEvent(Level level)
|
|
||||||
{
|
|
||||||
if (level != null) {
|
|
||||||
eventApi.worldLoadEvent(WorldWrapper.getWorldWrapper(level));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void worldUnloadEvent(Level level)
|
|
||||||
{
|
|
||||||
if (level != null) {
|
|
||||||
eventApi.worldUnloadEvent(WorldWrapper.getWorldWrapper(level));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Can someone tell me how to make this better
|
|
||||||
* @author Ran
|
|
||||||
*
|
|
||||||
* public void blockChangeEvent(BlockEventData event) {
|
|
||||||
* // we only care about certain block events
|
|
||||||
* if (event.getClass() == BlockEventData.BreakEvent.class ||
|
|
||||||
* event.getClass() == BlockEventData.EntityPlaceEvent.class ||
|
|
||||||
* event.getClass() == BlockEventData.EntityMultiPlaceEvent.class ||
|
|
||||||
* event.getClass() == BlockEventData.FluidPlaceBlockEvent.class ||
|
|
||||||
* event.getClass() == BlockEventData.PortalSpawnEvent.class)
|
|
||||||
* {
|
|
||||||
* IChunkWrapper chunk = new ChunkWrapper(event.getWorld().getChunk(event.getPos()));
|
|
||||||
* DimensionTypeWrapper dimType = DimensionTypeWrapper.getDimensionTypeWrapper(event.getWorld().dimensionType());
|
|
||||||
*
|
|
||||||
* // recreate the LOD where the blocks were changed
|
|
||||||
* eventApi.blockChangeEvent(chunk, dimType);
|
|
||||||
* }
|
|
||||||
* }
|
|
||||||
*/
|
|
||||||
public void blockChangeEvent(LevelAccessor world, BlockPos pos) {
|
|
||||||
IChunkWrapper chunk = new ChunkWrapper(world.getChunk(pos), world);
|
|
||||||
DimensionTypeWrapper dimType = DimensionTypeWrapper.getDimensionTypeWrapper(world.dimensionType());
|
|
||||||
|
|
||||||
// recreate the LOD where the blocks were changed
|
|
||||||
eventApi.blockChangeEvent(chunk, dimType);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final List<Integer> KEY_TO_CHECK_FOR = List.of(GLFW.GLFW_KEY_F6, GLFW.GLFW_KEY_F8);
|
|
||||||
|
|
||||||
HashSet<Integer> previousKeyDown = new HashSet<Integer>();
|
|
||||||
|
|
||||||
public void onKeyInput() {
|
|
||||||
ILodConfigWrapperSingleton CONFIG = SingletonHandler.get(ILodConfigWrapperSingleton.class);
|
|
||||||
if (CONFIG.client().advanced().debugging().getDebugKeybindingsEnabled())
|
|
||||||
{
|
|
||||||
HashSet<Integer> currectKeyDown = new HashSet<Integer>();
|
|
||||||
|
|
||||||
// Note: Minecraft's InputConstants is same as GLFW Key values
|
|
||||||
//TODO: Use mixin to hook directly into the GLFW Keyboard event in minecraft KeyboardHandler
|
|
||||||
// Check all keys we need
|
|
||||||
for (int i = InputConstants.KEY_A; i <= InputConstants.KEY_Z; i++) {
|
|
||||||
if (InputConstants.isKeyDown(Minecraft.getInstance().getWindow().getWindow(), i)) {
|
|
||||||
currectKeyDown.add(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (int i : KEY_TO_CHECK_FOR) {
|
|
||||||
if (InputConstants.isKeyDown(Minecraft.getInstance().getWindow().getWindow(), i)) {
|
|
||||||
currectKeyDown.add(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Diff and trigger events
|
|
||||||
for (int c : currectKeyDown) {
|
|
||||||
if (!previousKeyDown.contains(c)) {
|
|
||||||
ClientApi.INSTANCE.keyPressedEvent(c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update the set
|
|
||||||
previousKeyDown = currectKeyDown;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,96 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of the Distant Horizon mod (formerly the LOD Mod),
|
|
||||||
* licensed under the GNU GPL v3 License.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2020 James Seibel
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU 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 General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.seibel.lod.fabric;
|
|
||||||
|
|
||||||
import com.seibel.lod.common.LodCommonMain;
|
|
||||||
import com.seibel.lod.core.ModInfo;
|
|
||||||
import com.seibel.lod.core.api.ApiShared;
|
|
||||||
import com.seibel.lod.core.api.ClientApi;
|
|
||||||
import com.seibel.lod.core.handlers.dependencyInjection.ModAccessorHandler;
|
|
||||||
import com.seibel.lod.core.handlers.dependencyInjection.SingletonHandler;
|
|
||||||
import com.seibel.lod.core.wrapperInterfaces.modAccessor.IModChecker;
|
|
||||||
import com.seibel.lod.core.wrapperInterfaces.modAccessor.IOptifineAccessor;
|
|
||||||
import com.seibel.lod.core.wrapperInterfaces.modAccessor.ISodiumAccessor;
|
|
||||||
import com.seibel.lod.core.wrapperInterfaces.modAccessor.IStarlightAccessor;
|
|
||||||
import com.seibel.lod.fabric.networking.NetworkHandler;
|
|
||||||
import com.seibel.lod.fabric.wrappers.modAccessor.ModChecker;
|
|
||||||
import com.seibel.lod.fabric.wrappers.modAccessor.OptifineAccessor;
|
|
||||||
import com.seibel.lod.fabric.wrappers.modAccessor.SodiumAccessor;
|
|
||||||
import com.seibel.lod.fabric.wrappers.modAccessor.StarlightAccessor;
|
|
||||||
import com.seibel.lod.fabric.wrappers.FabricDependencySetup;
|
|
||||||
|
|
||||||
import net.fabricmc.api.ClientModInitializer;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize and setup the Mod. <br>
|
|
||||||
* If you are looking for the real start of the mod
|
|
||||||
* check out the ClientProxy.
|
|
||||||
*
|
|
||||||
* @author coolGi2007
|
|
||||||
* @author Ran
|
|
||||||
* @version 12-1-2021
|
|
||||||
*/
|
|
||||||
public class Main implements ClientModInitializer
|
|
||||||
{
|
|
||||||
// This is a client mod so it should implement ClientModInitializer and in fabric.mod.json it should have "environment": "client"
|
|
||||||
// Once it works on servers change the implement to ModInitializer and in fabric.mod.json it should be "environment": "*"
|
|
||||||
|
|
||||||
public static ClientProxy client_proxy;
|
|
||||||
|
|
||||||
|
|
||||||
// Do if implements ClientModInitializer
|
|
||||||
// This loads the mod before minecraft loads which causes a lot of issues
|
|
||||||
@Override
|
|
||||||
public void onInitializeClient() {
|
|
||||||
// no.
|
|
||||||
}
|
|
||||||
|
|
||||||
// This loads the mod after minecraft loads which doesn't causes a lot of issues
|
|
||||||
public static void init() {
|
|
||||||
LodCommonMain.initConfig();
|
|
||||||
LodCommonMain.startup(null, false, new NetworkHandler());
|
|
||||||
FabricDependencySetup.createInitialBindings();
|
|
||||||
FabricDependencySetup.finishBinding();
|
|
||||||
ApiShared.LOGGER.info(ModInfo.READABLE_NAME + ", Version: " + ModInfo.VERSION);
|
|
||||||
|
|
||||||
// Check if this works
|
|
||||||
client_proxy = new ClientProxy();
|
|
||||||
client_proxy.registerEvents();
|
|
||||||
if (SingletonHandler.get(IModChecker.class).isModLoaded("sodium")) {
|
|
||||||
ModAccessorHandler.bind(ISodiumAccessor.class, new SodiumAccessor());
|
|
||||||
}
|
|
||||||
if (SingletonHandler.get(IModChecker.class).isModLoaded("starlight")) {
|
|
||||||
ModAccessorHandler.bind(IStarlightAccessor.class, new StarlightAccessor());
|
|
||||||
}
|
|
||||||
if (SingletonHandler.get(IModChecker.class).isModLoaded("optifine")) {
|
|
||||||
ModAccessorHandler.bind(IOptifineAccessor.class, new OptifineAccessor());
|
|
||||||
}
|
|
||||||
|
|
||||||
ModAccessorHandler.finishBinding();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void initServer() {
|
|
||||||
LodCommonMain.initConfig();
|
|
||||||
LodCommonMain.startup(null, true, new NetworkHandler());
|
|
||||||
FabricDependencySetup.createInitialBindings();
|
|
||||||
FabricDependencySetup.finishBinding();
|
|
||||||
ApiShared.LOGGER.info(ModInfo.READABLE_NAME + ", Version: " + ModInfo.VERSION);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
package com.seibel.lod.fabric.mixins;
|
|
||||||
|
|
||||||
import com.seibel.lod.fabric.Main;
|
|
||||||
import net.minecraft.server.dedicated.DedicatedServer;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
|
||||||
|
|
||||||
@Mixin(DedicatedServer.class)
|
|
||||||
public class MixinDedicatedServer {
|
|
||||||
@Inject(method = "initServer", at = @At("TAIL"))
|
|
||||||
public void initServer(CallbackInfoReturnable<Boolean> cir) {
|
|
||||||
Main.initServer();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
package com.seibel.lod.fabric.mixins;
|
|
||||||
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
|
||||||
|
|
||||||
import com.mojang.blaze3d.systems.RenderSystem;
|
|
||||||
import com.seibel.lod.core.handlers.dependencyInjection.SingletonHandler;
|
|
||||||
import com.seibel.lod.core.wrapperInterfaces.config.ILodConfigWrapperSingleton;
|
|
||||||
|
|
||||||
import net.minecraft.client.Camera;
|
|
||||||
import net.minecraft.client.renderer.FogRenderer;
|
|
||||||
import net.minecraft.client.renderer.FogRenderer.FogMode;
|
|
||||||
import net.minecraft.world.effect.MobEffects;
|
|
||||||
import net.minecraft.world.entity.Entity;
|
|
||||||
import net.minecraft.world.entity.LivingEntity;
|
|
||||||
import net.minecraft.world.level.material.FogType;
|
|
||||||
|
|
||||||
@Mixin(FogRenderer.class)
|
|
||||||
public class MixinFogRenderer {
|
|
||||||
private static final ILodConfigWrapperSingleton CONFIG = SingletonHandler.get(ILodConfigWrapperSingleton.class);
|
|
||||||
|
|
||||||
// Using this instead of Float.MAX_VALUE because Sodium don't like it.
|
|
||||||
private static final float A_REALLY_REALLY_BIG_VALUE = 420694206942069.F;
|
|
||||||
private static final float A_EVEN_LARGER_VALUE = 42069420694206942069.F;
|
|
||||||
|
|
||||||
@Inject(at = @At("RETURN"), method = "setupFog(Lnet/minecraft/client/Camera;Lnet/minecraft/client/renderer/FogRenderer$FogMode;FZ)V")
|
|
||||||
private static void disableSetupFog(Camera camera, FogMode fogMode, float f, boolean bl, CallbackInfo callback) {
|
|
||||||
FogType fogTypes = camera.getFluidInCamera();
|
|
||||||
Entity entity = camera.getEntity();
|
|
||||||
boolean isUnderWater = (entity instanceof LivingEntity) && ((LivingEntity)entity).hasEffect(MobEffects.BLINDNESS);
|
|
||||||
if (!isUnderWater) {
|
|
||||||
if (fogMode == FogMode.FOG_TERRAIN && fogTypes == FogType.NONE && CONFIG.client().graphics().fogQuality().getDisableVanillaFog()) {
|
|
||||||
RenderSystem.setShaderFogStart(A_REALLY_REALLY_BIG_VALUE);
|
|
||||||
RenderSystem.setShaderFogEnd(A_EVEN_LARGER_VALUE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
package com.seibel.lod.fabric.mixins;
|
|
||||||
|
|
||||||
import com.seibel.lod.fabric.Main;
|
|
||||||
import net.minecraft.client.Minecraft;
|
|
||||||
import net.minecraft.client.main.GameConfig;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Loads the mod after minecraft loads.
|
|
||||||
* @author Ran
|
|
||||||
*/
|
|
||||||
@Mixin(value = Minecraft.class)
|
|
||||||
public class MixinMinecraft {
|
|
||||||
@Inject(method = "<init>", at = @At("TAIL"))
|
|
||||||
private void startMod(GameConfig gameConfig, CallbackInfo ci) {
|
|
||||||
Main.init();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
package com.seibel.lod.fabric.mixins.events;
|
|
||||||
|
|
||||||
import com.seibel.lod.fabric.Main;
|
|
||||||
import net.minecraft.client.Minecraft;
|
|
||||||
import net.minecraft.core.BlockPos;
|
|
||||||
import net.minecraft.network.protocol.game.ClientGamePacketListener;
|
|
||||||
import net.minecraft.network.protocol.game.ClientboundBlockUpdatePacket;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If someone has a better way to do this then please let me know.
|
|
||||||
*
|
|
||||||
* @author Ran
|
|
||||||
*/
|
|
||||||
@Mixin(ClientboundBlockUpdatePacket.class)
|
|
||||||
public abstract class MixinBlockUpdate {
|
|
||||||
@Shadow public abstract BlockPos getPos();
|
|
||||||
|
|
||||||
@Inject(method = "handle(Lnet/minecraft/network/protocol/game/ClientGamePacketListener;)V", at = @At("TAIL"))
|
|
||||||
private void onBlockUpdate(ClientGamePacketListener clientGamePacketListener, CallbackInfo ci) {
|
|
||||||
Main.client_proxy.blockChangeEvent(Minecraft.getInstance().player.clientLevel, this.getPos());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user