Compare commits

..

2 Commits

Author SHA1 Message Date
Leonardo a314f0fe79 Pregen test 2 2021-11-03 20:02:15 +01:00
Leonardo d8091ab62a Pregen test 2021-11-03 19:25:27 +01:00
182 changed files with 13621 additions and 13694 deletions
-30
View File
@@ -24,33 +24,3 @@ run
# Files from Forge MDK
logs
forge*changelog.txt
.architectury-transformer/
build/
*.ipr
run/
*.iws
out/
*.iml
.gradle/
output/
bin/
libs/
.classpath
.project
.idea/
classes/
.metadata
.vscode
.settings
*.launch
**/src/generated/
Merged/
# file from notepad++
*.bak
# file genearated via MC version switching using preprocessor
build.properties
-202
View File
@@ -1,202 +0,0 @@
# use Eclipse's JDK
image: gradle:eclipse-temurin
# all stages need to be defined here
stages:
- build_19_1
- build_19
- build_18_2
- build_18_1
- build_17_1
- build_16_5
variables:
# Pull core when building
GIT_SUBMODULE_STRATEGY: recursive
before_script:
- echo $CI_JOB_ID
# Writing GE_JOB_ID variable to environment file, will need the value in the next stage.
- echo GE_JOB_ID=$CI_JOB_ID >> generate_jars.env
# 1.16.5 build
build_16_5:
stage: build_16_5
script:
- echo "Building 1.16.5..."
- ./gradlew deleteMerged -PmcVer="1.16.5" --gradle-user-home cache/;
- ./gradlew clean -PmcVer="1.16.5" --gradle-user-home cache/;
- ./gradlew core:build -PmcVer="1.16.5" --gradle-user-home cache/;
- ./gradlew build -PmcVer="1.16.5" --gradle-user-home cache/;
- ./gradlew mergeJars -PmcVer="1.16.5" --gradle-user-home cache/;
image: eclipse-temurin:17
artifacts:
name: "Merged_NightlyBuild_1_16_5-${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.17.1 build
build_17_1:
stage: build_17_1
script:
- echo "Building 1.17.1..."
- ./gradlew deleteMerged -PmcVer="1.17.1" --gradle-user-home cache/;
- ./gradlew clean -PmcVer="1.17.1" --gradle-user-home cache/;
- ./gradlew core:build -PmcVer="1.17.7" --gradle-user-home cache/;
- ./gradlew build -PmcVer="1.17.1" --gradle-user-home cache/;
- ./gradlew mergeJars -PmcVer="1.17.1" --gradle-user-home cache/;
image: eclipse-temurin:17
artifacts:
name: "Merged_NightlyBuild_1_17_1-${CI_COMMIT_SHORT_SHA}-${CI_COMMIT_TIMESTAMP}"
paths:
- 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.18.1 build
build_18_1:
stage: build_18_1
script:
- echo "Building 1.18.1..."
- ./gradlew deleteMerged -PmcVer="1.18.1" --gradle-user-home cache/; # make sure any previously merged jars are removed before running this job
- ./gradlew clean -PmcVer="1.18.1" --gradle-user-home cache/;
- ./gradlew core:build -PmcVer="1.18.1" --gradle-user-home cache/;
- ./gradlew build -PmcVer="1.18.1" --gradle-user-home cache/;
- ./gradlew mergeJars -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:
# relative to the root directory
- Merged
expire_in: 1 day
when: always
cache:
key: "gradleCache"
policy: pull-push
paths:
- .gradle
- cache/
allow_failure: true
# 1.18.2 build
build_18_2:
stage: build_18_2
script:
- echo "Building 1.18.2..."
- ./gradlew deleteMerged -PmcVer="1.18.2" --gradle-user-home cache/;
- ./gradlew clean -PmcVer="1.18.2" --gradle-user-home cache/;
- ./gradlew core:build -PmcVer="1.18.2" --gradle-user-home cache/;
- ./gradlew build -PmcVer="1.18.2" --gradle-user-home cache/;
- ./gradlew mergeJars -PmcVer="1.18.2" --gradle-user-home cache/;
image: eclipse-temurin:17
artifacts:
name: "Merged_NightlyBuild_1_18_2-${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.19 build
build_19:
stage: build_19
script:
- echo "Building 1.19..."
- ./gradlew deleteMerged -PmcVer="1.19" --gradle-user-home cache/;
- ./gradlew clean -PmcVer="1.19" --gradle-user-home cache/;
- ./gradlew core:build -PmcVer="1.19" --gradle-user-home cache/;
- ./gradlew build -PmcVer="1.19" --gradle-user-home cache/;
- ./gradlew mergeJars -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
# 1.19.1 build
build_19_1:
stage: build_19_1
script:
- echo "Building 1.19.1..."
- ./gradlew deleteMerged -PmcVer="1.19.1" --gradle-user-home cache/;
- ./gradlew clean -PmcVer="1.19.1" --gradle-user-home cache/;
- ./gradlew core:build -PmcVer="1.19.1" --gradle-user-home cache/;
- ./gradlew build -PmcVer="1.19.1" --gradle-user-home cache/;
- ./gradlew mergeJars -PmcVer="1.19.1" --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
#deploy:
# stage: deploy
# image: registry.gitlab.com/gitlab-org/release-cli:latest
# script:
# - echo 'running release_job'
# - echo 'Previous Job ID is printed below'
# - echo $GE_JOB_ID
# # Specifying that this job requires artifacts from the previous job to succeed
# needs:
# - job: build
# artifacts: true
# release:
# name: 'Unstable Jars for Latest Commit' #: $CI_COMMIT_SHORT_SHA'
# description: 'Created automatically using the release-cli.'
# # tag_name is a mendatory field and can not be an empty string
# tag_name: 'Unstable-$CI_COMMIT_SHORT_SHA'
# assets:
# links:
# - name: 'Fabric Jars'
# url: 'https://gitlab.com/jeseibel/minecraft-lod-mod/cw/-/jobs/${GE_JOB_ID}/artifacts/file/fabric/build/libs'
# - name: 'Forge Jars'
# url: 'https://gitlab.com/jeseibel/minecraft-lod-mod/cw/-/jobs/${GE_JOB_ID}/artifacts/file/forge/build/libs'
-4
View File
@@ -1,4 +0,0 @@
[submodule "core"]
path = core
url = https://gitlab.com/jeseibel/distant-horizons-core.git
branch = main
-43
View File
@@ -1,43 +0,0 @@
# 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
# Fabric mod versions
modmenu_version=1.16.22
starlight_version_fabric=
phosphor_version_fabric=
lithium_version=mc1.16.5-0.6.6
sodium_version=3488820
iris_version=1.16.x-v1.1.4
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
-43
View File
@@ -1,43 +0,0 @@
# 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
# 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=3605275
iris_version=1.17.x-v1.1.4
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
-43
View File
@@ -1,43 +0,0 @@
# 1.18.1 version
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_version=0.13.3
fabric_api_version=0.46.6+1.18
# Fabric mod versions
modmenu_version=3.0.1
starlight_version_fabric=3554912
phosphor_version_fabric=3573395
lithium_version=mc1.18.1-0.7.7
sodium_version=3605309
iris_version=1.18.x-v1.1.4
bclib_version=1.2.5
immersive_portals_version = v1.0.4-1.18
# 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
# Forge loader
forge_version=39.1.2
# Forge mod versions
starlight_version_forge=3559934
terraforged_version=
# Forge mod run
# 0 = Dont 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
-43
View File
@@ -1,43 +0,0 @@
# 1.18.2 version based stuff
java_version = 17
minecraft_version=1.18.2
parchment_version=2022.03.13
compatible_minecraft_versions=["1.18.2"]
# Fabric loader
fabric_loader_version=0.13.3
fabric_api_version=0.48.0+1.18.2
# Fabric mod versions
modmenu_version=3.1.0
starlight_version_fabric=3667443
phosphor_version_fabric=3573395
lithium_version=mc1.18.2-0.7.9
sodium_version=3669187
iris_version=1.18.x-v1.2.2
immersive_portals_version = v1.0.4-1.18
bclib_version=0
# 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
# Forge loader
forge_version=40.0.18
# 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
-43
View File
@@ -1,43 +0,0 @@
# 1.18.2 version based stuff
java_version = 17
minecraft_version=1.19.1
parchment_version=2022.03.13
compatible_minecraft_versions=["1.19.1"]
# Fabric loader
fabric_loader_version=0.14.8
fabric_api_version=0.58.5+1.19.1
# Fabric mod versions
modmenu_version=4.0.0
starlight_version_fabric=0
phosphor_version_fabric=0
lithium_version=0
sodium_version=3820973
iris_version=1.19.x-v1.2.6
immersive_portals_version = 0
bclib_version=0
# 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
# Forge loader
forge_version=42.0.0
# 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
-43
View File
@@ -1,43 +0,0 @@
# 1.18.2 version based stuff
java_version = 17
minecraft_version=1.19
parchment_version=2022.03.13
compatible_minecraft_versions=["1.19"]
# Fabric loader
fabric_loader_version=0.14.8
fabric_api_version=0.57.0+1.19
# Fabric mod versions
modmenu_version=4.0.0
starlight_version_fabric=0
phosphor_version_fabric=0
lithium_version=0
sodium_version=3820973
iris_version=1.19.x-v1.2.6
immersive_portals_version = 0
bclib_version=0
# 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
# Forge loader
forge_version=41.0.94
# 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
Binary file not shown.
-165
View File
@@ -1,165 +0,0 @@
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.
+23 -122
View File
@@ -1,8 +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
> A mod that adds a Level of Detail System to Minecraft
# What is Distant Horizons?
# Distant Horizons
This mod adds a Level Of Detail (LOD) system to Minecraft.\
This implementation renders simplified chunks outside the normal render distance\
@@ -11,126 +7,42 @@ 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.\
If you want to see a quick demo, check out a video covering the mod here:
<a href="https://youtu.be/_04BZ8W2bDM" target="_blank">![Minecraft Level Of Detail (LOD) mod - Alpha 1.6.3](https://cdn.ko-fi.com/cdn/useruploads/png_ef4d209d-50d9-462f-b31f-92e42ec3e260cover.jpg?v=c1097a5b-029c-4484-bec3-80ff58c5d239)</a>
### Versions
This branch is for these versions of Minecraft
- 1.19.1
- 1.19
- 1.18.2
- 1.18.1 & 1.18
- 1.17.1 & 1.17
- 1.16.5 & 1.16.4
Architectury version: 3.4-SNAPSHOT\
Architectury loom version: 0.12.0-SNAPSHOT\
Java Compiler plugin: Manifold Preprocessor
#### 1.19.1 mods
Forge version: 42.0.0\
Fabric version: 0.14.8\
Fabric API version: 0.58.5+1.19.1\
Modmenu version: 4.0.0
#### 1.19 mods
Forge version: 41.0.94\
Fabric version: 0.14.8\
Fabric API version: 0.57.0+1.19\
Modmenu version: 4.0.0
#### 1.18.2 mods
Forge version: 40.0.18\
Fabric version: 0.13.3\
Fabric API version: 0.48.0+1.18.2\
Modmenu version: 3.1.0
#### 1.18.1 mods
Forge version: 39.1.2\
Fabric version: 0.13.3\
Fabric API version: 0.42.6+1.18\
Modmenu version: 3.0.1
#### 1.17.1 mods
Forge version: 37.1.1\
Fabric version: 0.13.2\
Fabric API version: 0.46.1+1.17\
Modmenu version: 2.0.14
#### 1.16.5 mods
Forge version: 36.2.28\
Fabric vetsion: 0.13.2\
Fabric API version: 0.42.0+1.16\
Modmenu version: 1.16.22
<a href="https://www.youtube.com/watch?v=H2tnvEVbO1c" target="_blank">![Minecraft Level Of Detail (LOD) mod - Alpha 1.4](https://i.ytimg.com/vi_webp/H2tnvEVbO1c/mqdefault.webp)</a>
Forge version: 1.16.5-36.1.0
Notes:\
This version has been confirmed to work in IDE and Retail Minecraft with ether the Fabric or Forge mod-loader.
This version has been confirmed to work in Eclipse and Retail Minecraft.\
(Retail running forge version 1.16.5-36.1.0)
## Source Code Installation
## source code installation
#### Nightlly builds
This mod has an autobuild system to automatically build the mod on each commit
- 1.19.1: https://gitlab.com/jeseibel/minecraft-lod-mod/-/jobs/artifacts/1.6.4a_dev/download?job=build_19_1
- 1.19: https://gitlab.com/jeseibel/minecraft-lod-mod/-/jobs/artifacts/1.6.4a_dev/download?job=build_19
- 1.18.2: https://gitlab.com/jeseibel/minecraft-lod-mod/-/jobs/artifacts/1.6.4a_dev/download?job=build_18_2
- 1.18.1: https://gitlab.com/jeseibel/minecraft-lod-mod/-/jobs/artifacts/1.6.4a_dev/download?job=build_18_1
- 1.17.1: https://gitlab.com/jeseibel/minecraft-lod-mod/-/jobs/artifacts/1.6.4a_dev/download?job=build_17_1
- 1.16.5: https://gitlab.com/jeseibel/minecraft-lod-mod/-/jobs/artifacts/1.6.4a_dev/download?job=build_16_5
See the Forge Documentation online for more detailed instructions:\
http://mcforge.readthedocs.io/en/latest/gettingstarted/
See the Fabric Documentation online for more detailed instructions:\
https://fabricmc.net/wiki/tutorial:setup
1. Create a system variable called "JAVA_MC_HOME" with the location of the JDK 1.8.0_251 (This is needed for gradle to work correctly)
2. replace JAVA_HOME with JAVA_MC_HOME in gradle.bat
3. open a command line in the project folder
### Prerequisites
* A Java Development Kit (JDK) for Java 17 (recommended) or newer. Visit https://www.oracle.com/java/technologies/downloads/ for installers.
* Git or someway to clone git projects. Visit https://git-scm.com/ for installers.
* (Not required) Any Java IDE with plugins that support Manifold, for example Intellij IDEA.
**If using IntelliJ:**
0. Install Manifold plugin
1. open IDEA and import the build.gradle
2. refresh the Gradle project in IDEA if required
**If using Ecplise: (Note that Eclispe currently doesn't support Manifold's preprocessor!)**
**If using Ecplise:**
1. run the command: `./gradlew geneclipseruns`
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 1.8.0_251 installed. (This is needed so that eclipse can run minecraft)
4. Import the project into eclipse
## Switching Versions
This branch support 6 built versions:
- 1.19.1
- 1.19
- 1.18.2
- 1.18.1 (which also runs on 1.18)
- 1.17.1 (which also runs on 1.17)
- 1.16.5 (which also runs 1.16.4)
**If using IntelliJ:**
1. open IDEA and import the build.gradle
2. run the command: `./gradlew genIntellijRuns`
3. refresh the Gradle project in IDEA if required
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.)
>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
## Compiling
**Using GUI**
1. Download the zip of the project and extract it
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
4. Run the command: `./gradlew assemble`
5. Then run command: `./gradlew mergeJars`
6. The compiled jar file will be in the folder `Merged`
**If in terminal:**
1. `git clone -b 1.6.4a_dev --recurse-submodules https://gitlab.com/jeseibel/minecraft-lod-mod.git`
2. `cd minecraft-lod-mod`
3. `./gradlew assemble`
4. `./gradlew mergeJars`
5. The compiled jar file will be in the folder `Merged`
>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.
1. open a command line in the project folder
2. run the command: `./gradlew build`
3. the compiled jar file will be in the folder `build\libs`
## Other commands
@@ -144,24 +56,13 @@ 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.
Source code uses Mojang mappings & [Parchment](https://parchmentmc.org/) mappings.
Source code uses Mojang mappings.
To generate the source code run `./gradlew genSources`\
If your IDE fails to auto-detect the sources JAR when browsing Minecraft classes manually select the JAR file ending with -sources.jar when prompted by your IDE
The source code can be 'created' with the `./eclipse` command and can be found in the following path:\
`minecraft-lod-mod\build\fg_cache\mcp\ VERSION \joined\ RANDOM_STRING \patch\output.jar`
In IntelliJ it's at the top where it says choose sources when browsing Minecraft classes
## Useful commands
Build only Fabric: `./gradlew fabric:assemble` or `./gradlew fabric:build`\
Build only Forge: `./gradlew fabric:assemble` or `./gradlew forge:build`\
Run the Fabric client (for debugging): `./gradlew fabric:runClient`\
Run the Forge client (for debugging): `./gradlew forge:runClient`
## Open Source Acknowledgements
XZ for Java (data compression)\
https://tukaani.org/xz/java.html
DHJarMerger (To merge multiple mod versions into one jar)\
https://github.com/Ran-helo/DHJarMerger
+390
View File
@@ -0,0 +1,390 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<profiles version="21">
<profile kind="CodeFormatterProfile" name="Eclipse (James' Edit)" version="21">
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_ellipsis" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_for_statment" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_javadoc_comments" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.indentation.size" value="4"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_enum_constant_declaration" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.align_with_spaces" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.continuation_indentation" value="2"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_before_code_block" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_switch_case_expressions" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_package" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.indent_root_tags" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.enabling_tag" value="@formatter:on"/>
<setting id="org.eclipse.jdt.core.formatter.comment.count_line_length_from_starting_position" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_record_components" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_multiplicative_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_logical_operator" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_annotation_declaration_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_record_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_enum_constant" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_multiplicative_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_abstract_method" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.keep_enum_constant_declaration_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.align_variable_declarations_on_columns" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_catch_clause" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.keep_anonymous_type_declaration_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_switch_case_expressions" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_shift_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block" value="next_line"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_end_of_code_block" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_bitwise_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_type_parameters" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_compact_loops" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.keep_simple_for_body_on_same_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_unary_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_annotation" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_ellipsis" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_enum_constant" value="49"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.text_block_indentation" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.align_type_members_on_columns" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_assignment" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_module_statements" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.align_tags_names_descriptions" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_if_then_body_block_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.align_assignment_statements_on_columns" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block_in_case" value="next_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_conditional_expression_chain" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_header" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_type_annotations" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_assertion_message_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_method_declaration" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.align_fields_grouping_blank_lines" value="2147483647"/>
<setting id="org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_bitwise_operator" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration" value="next_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_resources_in_try" value="80"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_source_code" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_field" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_method" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_not_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_type_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_html" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_method_delcaration" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_compact_if" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.indent_empty_lines" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_type_arguments" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_unary_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_package" value="49"/>
<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_label" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_arrow_in_switch_case" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_record_header" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_bitwise_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.indent_tag_description" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_record_constructor" value="next_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_string_concatenation" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_multiple_fields" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_array_initializer" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_shift_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_shift_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_simple_do_while_body_on_same_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_record_components" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_for_loop_header" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_additive_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.keep_simple_getter_setter_on_one_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_string_concatenation" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.join_lines_in_comments" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_record_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_relational_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_import_groups" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_logical_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_method_invocation" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_imports" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_record_declaration" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_switch_statement" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_arrow_in_switch_default" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.disabling_tag" value="@formatter:off"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_enum_constants" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_imports" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_end_of_method_body" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_if_while_statement" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_arrow_in_switch_case" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_block" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration" value="next_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.align_tags_descriptions_grouped" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.comment.line_length" value="80"/>
<setting id="org.eclipse.jdt.core.formatter.use_on_off_tags" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.keep_method_body_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_loop_body_block_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_method_declaration" value="next_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_type_declaration_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_additive_operator" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_record_constructor" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_relational_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_record_declaration_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration" value="next_line"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_lambda_body" value="next_line"/>
<setting id="org.eclipse.jdt.core.formatter.compact_else_if" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_parameter" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_relational_operator" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve" value="99"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_additive_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_string_concatenation" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_line_comments" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_record_declaration" value="next_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_after_code_block" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_conditional_expression" value="80"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_type" value="49"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_local_variable" value="49"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration" value="next_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_arrow_in_switch_default" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_between_different_tags" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_additive_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.join_wrapped_lines" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_field" value="49"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_conditional_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_shift_operator" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_try_clause" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.keep_code_block_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_record_components" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.tabulation.size" value="4"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_bitwise_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer" value="2"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_record_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_assignment_operator" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_switch" value="next_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_lambda_body_block_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_method" value="49"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_record_constructor_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_record_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_assertion_message" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_member_type" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_logical_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_record_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_relational_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_block_comments" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_last_class_body_declaration" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_body" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.keep_simple_while_body_on_same_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_logical_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_statement_group_in_switch" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_lambda_declaration" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_enum_declaration_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_constant" value="next_line"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_type_declaration" value="next_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_multiplicative_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_package" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.indent_parameter_description" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_code_block" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.tabulation.char" value="tab"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_string_concatenation" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.lineSplit" value="1200"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch" value="insert"/>
</profile>
</profiles>
@@ -0,0 +1,50 @@
<code_scheme name="Eclipse (James' Edit)" version="173">
<option name="RIGHT_MARGIN" value="1200" />
<JavaCodeStyleSettings>
<option name="JD_ALIGN_PARAM_COMMENTS" value="false" />
<option name="JD_ALIGN_EXCEPTION_COMMENTS" value="false" />
<option name="JD_ADD_BLANK_AFTER_DESCRIPTION" value="false" />
<option name="JD_P_AT_EMPTY_LINES" value="false" />
<option name="JD_KEEP_INVALID_TAGS" value="false" />
<option name="JD_DO_NOT_WRAP_ONE_LINE_COMMENTS" value="true" />
<option name="JD_KEEP_EMPTY_PARAMETER" value="false" />
<option name="JD_KEEP_EMPTY_EXCEPTION" value="false" />
<option name="JD_KEEP_EMPTY_RETURN" value="false" />
</JavaCodeStyleSettings>
<codeStyleSettings language="JAVA">
<option name="KEEP_CONTROL_STATEMENT_IN_ONE_LINE" value="false" />
<option name="KEEP_BLANK_LINES_IN_DECLARATIONS" value="10" />
<option name="KEEP_BLANK_LINES_IN_CODE" value="10" />
<option name="KEEP_BLANK_LINES_BEFORE_RBRACE" value="10" />
<option name="BLANK_LINES_BEFORE_PACKAGE" value="1" />
<option name="BRACE_STYLE" value="2" />
<option name="CLASS_BRACE_STYLE" value="2" />
<option name="METHOD_BRACE_STYLE" value="2" />
<option name="ELSE_ON_NEW_LINE" value="true" />
<option name="WHILE_ON_NEW_LINE" value="true" />
<option name="CATCH_ON_NEW_LINE" value="true" />
<option name="FINALLY_ON_NEW_LINE" value="true" />
<option name="INDENT_CASE_FROM_SWITCH" value="false" />
<option name="ALIGN_MULTILINE_PARAMETERS" value="false" />
<option name="ALIGN_MULTILINE_RESOURCES" value="false" />
<option name="SPACE_WITHIN_ARRAY_INITIALIZER_BRACES" value="true" />
<option name="SPACE_BEFORE_ARRAY_INITIALIZER_LBRACE" value="true" />
<option name="CALL_PARAMETERS_WRAP" value="1" />
<option name="METHOD_PARAMETERS_WRAP" value="1" />
<option name="RESOURCE_LIST_WRAP" value="5" />
<option name="EXTENDS_LIST_WRAP" value="1" />
<option name="THROWS_LIST_WRAP" value="1" />
<option name="EXTENDS_KEYWORD_WRAP" value="1" />
<option name="THROWS_KEYWORD_WRAP" value="1" />
<option name="METHOD_CALL_CHAIN_WRAP" value="1" />
<option name="TERNARY_OPERATION_WRAP" value="5" />
<option name="ARRAY_INITIALIZER_WRAP" value="1" />
<option name="METHOD_ANNOTATION_WRAP" value="0" />
<option name="CLASS_ANNOTATION_WRAP" value="0" />
<option name="FIELD_ANNOTATION_WRAP" value="0" />
<indentOptions>
<option name="USE_TAB_CHARACTER" value="true" />
<option name="KEEP_INDENTS_ON_EMPTY_LINES" value="true" />
</indentOptions>
</codeStyleSettings>
</code_scheme>
Binary file not shown.

After

Width:  |  Height:  |  Size: 113 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 81 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 191 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 172 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 194 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 174 KiB

+209 -378
View File
@@ -1,403 +1,234 @@
import io.github.ran.jarmerger.JarMergerPlugin
buildscript {
dependencies{
classpath files('plugins/DHJarMerger-1.0.jar')
repositories {
maven { url = 'https://files.minecraftforge.net' }
mavenCentral()
// potential replacement in case of problems:
// https://dist.creeper.host/Sponge/maven
maven { url = 'https://repo.spongepowered.org/maven/' }
// used to download and compile dependencies from git repos
maven { url 'https://jitpack.io' }
}
dependencies {
classpath group: 'net.minecraftforge.gradle', name: 'ForgeGradle', version: '3.+', changing: true
classpath group: 'org.spongepowered', name: 'mixingradle', version: '0.7-SNAPSHOT'
classpath 'com.github.jengelman.gradle.plugins:shadow:2.0.2'
}
}
apply plugin: 'net.minecraftforge.gradle'
apply plugin: 'org.spongepowered.mixin'
// Only edit below this line, the above code adds and enables the necessary things for Forge to be setup.
apply plugin: 'eclipse'
apply plugin: 'maven-publish'
apply plugin: 'com.github.johnrengelman.shadow'
plugins {
id "architectury-plugin" version "3.4-SNAPSHOT"
id "dev.architectury.loom" version "0.12.0-SNAPSHOT" apply false
}
version = 'a1.5.1'
group = 'com.seibel.lod'
archivesBaseName = 'Distant-Horizons_1.16.5'
apply plugin: "java"
apply plugin: "architectury-plugin"
apply plugin: "maven-publish"
apply plugin: JarMergerPlugin
archivesBaseName = rootProject.archives_base_name
version = rootProject.mod_version
group = rootProject.maven_group
sourceCompatibility = targetCompatibility = compileJava.sourceCompatibility = compileJava.targetCompatibility = '1.8' // Need this here so eclipse task generates correctly.
task printConfigurations {
doLast {task ->
println "Project Name: $name configurations:"
configurations.each {
println " $it.name"
println('Java: ' + System.getProperty('java.version') + ' JVM: ' + System.getProperty('java.vm.version') + '(' + System.getProperty('java.vendor') + ') Arch: ' + System.getProperty('os.arch'))
minecraft {
// The mappings can be changed at any time, and must be in the following format.
// snapshot_YYYYMMDD Snapshot are built nightly.
// stable_# Stables are built at the discretion of the MCP team.
// Use non-default mappings at your own risk. they may not always work.
// Simply re-run your setup task after changing the mappings to update your workspace.
mappings channel: 'official', version: '1.16.5'
// makeObfSourceJar = false // an Srg named sources jar is made by default. uncomment this to disable.
accessTransformer = file('src/main/resources/META-INF/accesstransformer.cfg')
// Default run configurations.
// These can be tweaked, removed, or duplicated as needed.
runs {
client {
workingDirectory project.file('run')
arg "-mixin.config=lod.mixins.json"
// Recommended logging data for a userdev environment
// The markers can be changed as needed.
// "SCAN": For mods scan.
// "REGISTRIES": For firing of registry events.
// "REGISTRYDUMP": For getting the contents of all registries.
property 'forge.logging.markers', 'REGISTRIES'
// Recommended logging level for the console
// You can set various levels here.
// Please read: https://stackoverflow.com/questions/2031163/when-to-use-the-different-log-levels
property 'forge.logging.console.level', 'debug'
mods {
examplemod {
source sourceSets.main
}
}
}
server {
workingDirectory project.file('run')
arg "-mixin.config=lod.mixins.json"
// Recommended logging data for a userdev environment
// The markers can be changed as needed.
// "SCAN": For mods scan.
// "REGISTRIES": For firing of registry events.
// "REGISTRYDUMP": For getting the contents of all registries.
property 'forge.logging.markers', 'REGISTRIES'
// Recommended logging level for the console
// You can set various levels here.
// Please read: https://stackoverflow.com/questions/2031163/when-to-use-the-different-log-levels
property 'forge.logging.console.level', 'debug'
mods {
examplemod {
source sourceSets.main
}
}
}
data {
workingDirectory project.file('run')
// Recommended logging data for a userdev environment
// The markers can be changed as needed.
// "SCAN": For mods scan.
// "REGISTRIES": For firing of registry events.
// "REGISTRYDUMP": For getting the contents of all registries.
property 'forge.logging.markers', 'REGISTRIES'
// Recommended logging level for the console
// You can set various levels here.
// Please read: https://stackoverflow.com/questions/2031163/when-to-use-the-different-log-levels
property 'forge.logging.console.level', 'debug'
// Specify the modid for data generation, where to output the resulting resource, and where to look for existing resources.
args '--mod', 'lod', '--all', '--output', file('src/generated/resources/'), '--existing', file('src/main/resources/')
mods {
examplemod {
source sourceSets.main
}
}
}
}
}
def writeBuildGradlePredefine(List<String> mcVers, int mcIndex) {
ArrayList<String> redefineList = new ArrayList<String>()
for (int i=0; i<mcVers.size(); i++) {
String mcStr = mcVers.get(i).replace(".", "_")
if (mcIndex<i) {
redefineList.add("PRE_MC_"+mcStr)
}
if (mcIndex==i) {
redefineList.add("MC_"+mcStr)
}
if (mcIndex>=i) {
redefineList.add("POST_MC_"+mcStr)
}
}
StringBuilder sb = new StringBuilder()
for (String s : redefineList) {
sb.append(s)
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.1"
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
}
println "Loading properties file at " + mcVersion + ".properties"
def props = new Properties()
props.load(new FileInputStream("$rootProject.rootDir/"+"$mcVersion"+".properties"))
props.each { prop ->
rootProject.ext.set(prop.key, prop.value)
// println "Added prop [key:" + prop.key + ", value:" + prop.value + "]"
}
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" : "1_19"
]
// Use this as sometimes multiple versions use the same access wideners
rootProject.ext.set("acsessWidenerVersion", mcVersionToAcsessWidenerVersion.get(mcVersion))
}
loadProperties()
architectury {
minecraft = rootProject.minecraft_version
}
// Include resources generated by data generators.
sourceSets.main.resources { srcDir 'src/generated/resources' }
// this is required so that we can use
// jitpack in the dependencies section below
repositories {
mavenCentral()
// used to download and compile dependencies from git repos
maven { url 'https://jitpack.io' }
}
// For parchment mappings
maven { url "https://maven.parchmentmc.org" }
configurations {
shadowMe
compileOnly.extendsFrom(embed)
}
// used to download and compile dependencies from git repos
maven { url 'https://jitpack.io' }
dependencies {
// Specify the version of Minecraft to use, If this is any group other then 'net.minecraft' it is assumed
// that the dep is a ForgeGradle 'patcher' dependency. And it's patches will be applied.
// The userdev artifact is a special name and will get all sorts of transformations applied to it.
minecraft 'net.minecraftforge:forge:1.16.5-36.1.0'
// For Manifold Preprocessor
maven { url 'https://oss.sonatype.org/content/repositories/snapshots/' }
// Required for importing Modrinth mods
maven {
name = "Modrinth"
url = "https://api.modrinth.com/maven"
content {
includeGroup "maven.modrinth"
compile 'org.tukaani:xz:1.9'
shadowMe 'org.tukaani:xz:1.9'
compile 'org.apache.commons:commons-compress:1.21'
shadowMe 'org.apache.commons:commons-compress:1.21'
// these were added to hopefully allow for cloning
// configuredFeatures to allow for safe
// multi threaded feature generation. Sadly I couldn't find
// a way to duplicate lambda functions (which features use)
// so for now I'm not sure what to do.
//implementation 'io.github.kostaskougios:cloning:1.10.3'
//
//implementation ('com.esotericsoftware:kryo:5.1.1') {
// exclude group: "org.objenesis"
//}
//implementation 'org.objenesis:objenesis:3.2'
// You may put jars on which you depend on in ./libs or you may define them like so..
// compile "some.group:artifact:version:classifier"
// compile "some.group:artifact:version"
// Real examples
// compile 'com.mod-buildcraft:buildcraft:6.0.8:dev' // adds buildcraft to the dev env
// compile 'com.googlecode.efficient-java-matrix-library:ejml:0.24' // adds ejml to the dev env
// The 'provided' configuration is for optional dependencies that exist at compile-time but might not at runtime.
// provided 'com.mod-buildcraft:buildcraft:6.0.8:dev'
// These dependencies get remapped to your current MCP mappings
// deobf 'com.mod-buildcraft:buildcraft:6.0.8:dev'
// For more info...
// http://www.gradle.org/docs/current/userguide/artifact_dependencies_tutorial.html
// http://www.gradle.org/docs/current/userguide/dependency_management.html
}
shadowJar {
duplicatesStrategy = DuplicatesStrategy.INCLUDE
configurations = [project.configurations.getByName("shadowMe")]
relocate 'org.tukaani', 'shaded.tukaani'
relocate 'org.apache.commons.compress', 'shaded.apache.commons.compress'
classifier = ''
}
reobf {
shadowJar {
dependsOn tasks.createMcpToSrg
mappings = tasks.createMcpToSrg.outputs.files.singleFile
}
}
artifacts {
archives tasks.shadowJar
}
// Example for how to get properties into the manifest for reading by the runtime..
jar {
manifest {
attributes([
"Specification-Title": "LOD",
"Specification-Version": "1", // We are version 1 of ourselves
"Implementation-Title": project.name,
"Implementation-Version": "1",
"Implementation-Timestamp": new Date().format("yyyy-MM-dd'T'HH:mm:ssZ"),
"MixinConfigs": "lod.mixins.json",
])
}
}
// Example configuration to allow publishing using the maven-publish task
// This is the preferred method to reobfuscate your jar file
jar.finalizedBy('reobfJar')
// However if you are in a multi-project build, dev time needs unobfed jar files, so you can delay the obfuscation until publishing by doing
//publish.dependsOn('reobfJar')
publishing {
publications {
mavenJava(MavenPublication) {
artifact jar
}
}
// Required for importing CursedForge mods
maven {
url "https://www.cursemaven.com"
content {
includeGroup "curse.maven"
}
}
// These 2 are for importing mods that arnt on CursedForge, Modrinth, GitHub, GitLab or anywhere opensource
flatDir {
dirs "${rootDir}/mods/fabric"
content {
includeGroup "fabric-mod"
}
}
flatDir {
dirs "${rootDir}/mods/forge"
content {
includeGroup "forge-mod"
repositories {
maven {
url "file:///${project.projectDir}/mcmodsrepo"
}
}
}
processResources {
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 replaceProperties = [
version : mod_version,
mod_name : mod_name,
authors : mod_authors,
description : mod_description,
homepage : mod_homepage,
source : mod_source,
issues : mod_issues,
minecraft_version : minecraft_version,
compatible_minecraft_versions: compatible_minecraft_versions,
java_version : java_version
]
// 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
replaceProperties.put 'project', project
filesMatching(resourceTargets) {
expand replaceProperties
}
intoTargets.each { target ->
if (file(target).exists()) {
copy {
from(sourceSets.main.resources) {
include resourceTargets
expand replaceProperties
}
into target
}
}
}
}
// Copies the correct accesswidener and renames it
task copyAccessWidener(type: Copy) {
from project(":common").file("src/main/resources/${rootProject.acsessWidenerVersion}.lod.accesswidener")
into(file("build/resources/main"))
rename "${rootProject.acsessWidenerVersion}.lod.accesswidener", "lod.accesswidener"
}
task copyCoreResources(type: Copy) {
from fileTree(project(":core").file("src/main/resources"))
into file("build/resources/main")
}
task copyCommonResources(type: Copy) {
from fileTree(project(":common").file("src/main/resources"))
into file("build/resources/main")
}
java {
withSourcesJar()
}
//runClient.enabled = false
//runServer.enabled = false
// this deletes the merged folder so we don't carry over
// the previous merges to each new build job in the CI/CD pipeline
task deleteMerged(type: Delete) {
delete files("./Merged")
}
// ===============================CORE Gradle basically================================
subprojects { p ->
if (p == project(":core")) {
apply plugin: "java"
apply plugin: "architectury-plugin"
apply plugin: "maven-publish"
apply plugin: "dev.architectury.loom"
p.archivesBaseName = rootProject.archives_base_name
p.version = rootProject.mod_version
p.group = rootProject.maven_group
loom {
silentMojangMappingsLicense()
}
configurations {
common
shadowMe
implementation.extendsFrom shadowMe
}
dependencies {
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)
if (rootProject.minecraft_version != "1.19" && rootProject.minecraft_version != "1.19.1")
parchment("org.parchmentmc.data:parchment-${rootProject.minecraft_version}:${rootProject.parchment_version}@zip")
else
parchment("org.parchmentmc.data:parchment-1.18.2:${rootProject.parchment_version}@zip") // As 1.19.x or higher doesnt have parchment mappings yet, we use 1.18.2 mapping
}
//Manifold
annotationProcessor "systems.manifold:manifold-preprocessor:${rootProject.manifold_version}"
// Toml
implementation("com.electronwill.night-config:toml:${rootProject.toml_version}")
// 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 unless working with fabric
modImplementation "net.fabricmc:fabric-loader:${rootProject.fabric_loader_version}"
}
// Allows the jar to run standalone
jar {
manifest {
attributes 'Implementation-Title': rootProject.archives_base_name,
'Implementation-Version': rootProject.mod_version,
'Main-Class': 'com.seibel.lod.core.JarMain'
// When changing the main of the jar change this line
}
}
task printConfigurations {
doLast {task ->
println "Project Name: $p.name configurations:"
configurations.each {
println " $it.name"
}
}
}
repositories {
mavenCentral()
// For parchment mappings
maven { url "https://maven.parchmentmc.org" }
// used to download and compile dependencies from git repos
maven { url 'https://jitpack.io' }
// For Manifold Preprocessor
maven { url 'https://oss.sonatype.org/content/repositories/snapshots/' }
// Required for importing Modrinth mods
maven {
name = "Modrinth"
url = "https://api.modrinth.com/maven"
content {
includeGroup "maven.modrinth"
}
}
// Required for importing CursedForge mods
maven {
url "https://www.cursemaven.com"
content {
includeGroup "curse.maven"
}
}
// These 2 are for importing mods that arnt on CursedForge, Modrinth, GitHub, GitLab or anywhere opensource
flatDir {
dirs "${rootDir}/mods/fabric"
content {
includeGroup "fabric-mod"
}
}
flatDir {
dirs "${rootDir}/mods/forge"
content {
includeGroup "forge-mod"
}
}
}
processResources {
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 replaceProperties = [
version : mod_version,
mod_name : mod_name,
authors : mod_authors,
description : mod_description,
homepage : mod_homepage,
source : mod_source,
issues : mod_issues,
minecraft_version : minecraft_version,
compatible_minecraft_versions: compatible_minecraft_versions,
java_version : java_version
]
// 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
replaceProperties.put 'project', project
filesMatching(resourceTargets) {
expand replaceProperties
}
intoTargets.each { target ->
if (file(target).exists()) {
copy {
from(sourceSets.main.resources) {
include resourceTargets
expand replaceProperties
}
into target
}
}
}
}
// Copies the correct accesswidener and renames it
task copyAccessWidener(type: Copy) {
from project(":common").file("src/main/resources/${rootProject.acsessWidenerVersion}.lod.accesswidener")
into(file(p.file("build/resources/main")))
rename "${rootProject.acsessWidenerVersion}.lod.accesswidener", "lod.accesswidener"
}
task copyCoreResources(type: Copy) {
from fileTree(project(":core").file("src/main/resources"))
into p.file("build/resources/main")
}
task copyCommonResources(type: Copy) {
from fileTree(project(":common").file("src/main/resources"))
into p.file("build/resources/main")
}
p.tasks.withType(JavaCompile) {
// Add Manifold Preprocessor
// def excapedMCVersion = rootProject.minecraft_version.replace(".", "_")
// options.compilerArgs += ['-Xplugin:Manifold', "-AMC_VERSION_${excapedMCVersion}"]
//
//options.compilerArgs += ['-deprecation']
//options.compilerArgs += ['-verbose']
//options.compilerArgs += ['-Xlint:unchecked']
//options.compilerArgs += ['-Xdiags:verbose']
//options.compilerArgs += ['-Xprint']
//options.compilerArgs += ['-XprintProcessorInfo']
//options.compilerArgs += ['-XprintRounds']
// println options.compilerArgs
// Set the java version
options.release = 8; // Core should use Java 8 no matter what
// TODO: make everything use java 8
// options.release = 8 // Use Java 8 for everything so back porting is easier
}
java {
withSourcesJar()
}
p.runClient.enabled = false
p.runServer.enabled = false
}
mixin {
add sourceSets.main, "lod.refmap.json"
}
-218
View File
@@ -1,218 +0,0 @@
apply plugin: "java"
apply plugin: "architectury-plugin"
apply plugin: "maven-publish"
apply plugin: "dev.architectury.loom"
archivesBaseName = rootProject.archives_base_name
version = rootProject.mod_version
group = rootProject.maven_group
architectury {
common(rootProject.enabled_platforms.split(","))
}
loom {
silentMojangMappingsLicense()
accessWidenerPath.set(project(":common").file("src/main/resources/${acsessWidenerVersion}.lod.accesswidener"))
}
configurations {
common
shadowMe
implementation.extendsFrom shadowMe
}
java {
withSourcesJar()
}
dependencies {
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)
if (rootProject.minecraft_version != "1.19" && rootProject.minecraft_version != "1.19.1")
parchment("org.parchmentmc.data:parchment-${rootProject.minecraft_version}:${rootProject.parchment_version}@zip")
else
parchment("org.parchmentmc.data:parchment-1.18.2:${rootProject.parchment_version}@zip") // As 1.19 dosnt have parchment mappings yet, we use 1.18.2 mapping
}
//Manifold
annotationProcessor "systems.manifold:manifold-preprocessor:${rootProject.manifold_version}"
// Toml
implementation("com.electronwill.night-config:toml:${rootProject.toml_version}")
// 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 unless working with fabric
modImplementation "net.fabricmc:fabric-loader:${rootProject.fabric_loader_version}"\
common(project(":core")) { transitive false }
shadowMe(project(":core")) { transitive false }
}
// Allows the jar to run standalone
jar {
manifest {
attributes 'Implementation-Title': rootProject.archives_base_name,
'Implementation-Version': rootProject.mod_version,
'Main-Class': 'com.seibel.lod.core.JarMain' // When changing the main of the jar change this line
}
}
publishing {
publications {
mavenCommon(MavenPublication) {
artifactId = rootProject.archives_base_name
from components.java
}
}
// See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing.
repositories {
// Add repositories to publish to here.
}
}
task printConfigurations {
doLast {task ->
println "Project Name: $name configurations:"
configurations.each {
println " $it.name"
}
}
}
repositories {
mavenCentral()
// For parchment mappings
maven { url "https://maven.parchmentmc.org" }
// used to download and compile dependencies from git repos
maven { url 'https://jitpack.io' }
// For Manifold Preprocessor
maven { url 'https://oss.sonatype.org/content/repositories/snapshots/' }
// Required for importing Modrinth mods
maven {
name = "Modrinth"
url = "https://api.modrinth.com/maven"
content {
includeGroup "maven.modrinth"
}
}
// Required for importing CursedForge mods
maven {
url "https://www.cursemaven.com"
content {
includeGroup "curse.maven"
}
}
// These 2 are for importing mods that arnt on CursedForge, Modrinth, GitHub, GitLab or anywhere opensource
flatDir {
dirs "${rootDir}/mods/fabric"
content {
includeGroup "fabric-mod"
}
}
flatDir {
dirs "${rootDir}/mods/forge"
content {
includeGroup "forge-mod"
}
}
}
// Copies the correct accesswidener and renames it
task copyAccessWidener(type: Copy) {
from project(":common").file("src/main/resources/${rootProject.acsessWidenerVersion}.lod.accesswidener")
into(file("build/resources/main"))
rename "${rootProject.acsessWidenerVersion}.lod.accesswidener", "lod.accesswidener"
}
task copyCoreResources(type: Copy) {
from fileTree(project(":core").file("src/main/resources"))
into file("build/resources/main")
}
task copyCommonResources(type: Copy) {
from fileTree(project(":common").file("src/main/resources"))
into file("build/resources/main")
}
processResources {
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 replaceProperties = [
version : mod_version,
mod_name : mod_name,
authors : mod_authors,
description : mod_description,
homepage : mod_homepage,
source : mod_source,
issues : mod_issues,
minecraft_version : minecraft_version,
compatible_minecraft_versions: compatible_minecraft_versions,
java_version : java_version
]
// 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
replaceProperties.put 'project', project
filesMatching(resourceTargets) {
expand replaceProperties
}
intoTargets.each { target ->
if (file(target).exists()) {
copy {
from(sourceSets.main.resources) {
include resourceTargets
expand replaceProperties
}
into target
}
}
}
}
println "Copying [common/src/main/resources/${acsessWidenerVersion}.lod.accesswidner] to [fabric/build/resources/main]."
copy {
from project(":common").file("src/main/resources/${acsessWidenerVersion}.lod.accesswidener")
into project(":fabric").file("build/resources/main")
rename "${acsessWidenerVersion}.lod.accesswidener", "lod.accesswidener"
}
tasks.withType(JavaCompile) {
// Add Manifold Preprocessor
// def excapedMCVersion = rootProject.minecraft_version.replace(".", "_")
// options.compilerArgs += ['-Xplugin:Manifold', "-AMC_VERSION_${excapedMCVersion}"]
//
//options.compilerArgs += ['-deprecation']
//options.compilerArgs += ['-verbose']
//options.compilerArgs += ['-Xlint:unchecked']
//options.compilerArgs += ['-Xdiags:verbose']
//options.compilerArgs += ['-Xprint']
//options.compilerArgs += ['-XprintProcessorInfo']
//options.compilerArgs += ['-XprintRounds']
// println options.compilerArgs
// Set the java version
options.compilerArgs += ['-Xplugin:Manifold']
options.release = rootProject.java_version as Integer
// TODO: make everything use java 8
// options.release = 8 // Use Java 8 for everything so back porting is easier
}
sourcesJar {
}
runClient.enabled = false
runServer.enabled = false
@@ -1,482 +0,0 @@
/*
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
* licensed under the GNU GPL 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 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;
import com.seibel.lod.core.wrapperInterfaces.config.ILodConfigWrapperSingleton.IClient.IAdvanced;
import com.seibel.lod.core.wrapperInterfaces.config.ILodConfigWrapperSingleton.IClient.IAdvanced.IDebugging.*;
/**
* This handles any configuration the user has access to.
* @author coolGi
* @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 = 32, 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 = 64)
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 _overdrawOffset = IAdvancedGraphics.OVERDRAW_OFFSET_DESC;
@ConfigAnnotations.Entry(minValue = -16, maxValue = 16)
public static int overdrawOffset = IAdvancedGraphics.OVERDRAW_OFFSET_MIN_DEFAULT_MAX.defaultValue;
@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 _enableCaveCulling = IAdvancedGraphics.ENABLE_CAVE_CULLING_DESC;
@ConfigAnnotations.Entry
public static boolean enableCaveCulling = IAdvancedGraphics.ENABLE_CAVE_CULLING_DEFAULT;
@ConfigAnnotations.FileComment
public static String _caveCullingHeight = IAdvancedGraphics.CAVE_CULLING_HEIGHT_DESC;
@ConfigAnnotations.Entry(minValue = -4096, maxValue = 4096)
public static int caveCullingHeight = IAdvancedGraphics.CAVE_CULLING_HEIGHT_MIN_DEFAULT_MAX.defaultValue;
@ConfigAnnotations.FileComment
public static String _earthCurveRatio = IAdvancedGraphics.EARTH_CURVE_RATIO_DESC;
@ConfigAnnotations.Entry(minValue = 0, maxValue = 5000)
public static int earthCurveRatio = IAdvancedGraphics.EARTH_CURVE_RATIO_MIN_DEFAULT_MAX.defaultValue;
/*
@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 _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(minValue = 0.0, maxValue = 1.0)
public static double multiDimensionRequiredSimilarity = IMultiplayer.MULTI_DIMENSION_REQUIRED_SIMILARITY_MIN_DEFAULT_MAX.defaultValue;
}
public static class Advanced
{
@ConfigAnnotations.ScreenEntry
public static Threading threading;
@ConfigAnnotations.ScreenEntry
public static Debugging debugging;
@ConfigAnnotations.ScreenEntry
public static Buffers buffers;
@ConfigAnnotations.FileComment
public static String _lodOnlyMode = IAdvanced.LOD_ONLY_MODE_DESC;
@ConfigAnnotations.Entry
public static boolean lodOnlyMode = IAdvanced.LOD_ONLY_MODE_DEFAULT;
public static class Threading
{
@ConfigAnnotations.FileComment
public static String _numberOfWorldGenerationThreads = IThreading.NUMBER_OF_WORLD_GENERATION_THREADS_DESC;
@ConfigAnnotations.Entry(minValue = 0.1, maxValue = 50.0)
public static double 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 _rendererType = IDebugging.RENDERER_TYPE_DESC;
@ConfigAnnotations.Entry
public static RendererType rendererType = IDebugging.RENDERER_TYPE_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;
@ConfigAnnotations.ScreenEntry
public static DebugSwitch debugSwitch;
public static class DebugSwitch {
/* The logging switches available:
* WorldGenEvent
* WorldGenPerformance
* WorldGenLoadEvent
* LodBuilderEvent
* RendererBufferEvent
* RendererGLEvent
* FileReadWriteEvent
* FileSubDimEvent
* NetworkEvent //NOT IMPL YET
*/
@ConfigAnnotations.FileComment
public static String _logWorldGenEvent = IDebugSwitch.LOG_WORLDGEN_EVENT_DESC;
@ConfigAnnotations.Entry
public static LoggerMode logWorldGenEvent = IDebugSwitch.LOG_WORLDGEN_EVENT_DEFAULT;
@ConfigAnnotations.FileComment
public static String _logWorldGenPerformance = IDebugSwitch.LOG_WORLDGEN_PERFORMANCE_DESC;
@ConfigAnnotations.Entry
public static LoggerMode logWorldGenPerformance = IDebugSwitch.LOG_WORLDGEN_PERFORMANCE_DEFAULT;
@ConfigAnnotations.FileComment
public static String _logWorldGenLoadEvent = IDebugSwitch.LOG_WORLDGEN_LOAD_EVENT_DESC;
@ConfigAnnotations.Entry
public static LoggerMode logWorldGenLoadEvent = IDebugSwitch.LOG_WORLDGEN_LOAD_EVENT_DEFAULT;
@ConfigAnnotations.FileComment
public static String _logLodBuilderEvent = IDebugSwitch.LOG_LODBUILDER_EVENT_DESC;
@ConfigAnnotations.Entry
public static LoggerMode logLodBuilderEvent = IDebugSwitch.LOG_LODBUILDER_EVENT_DEFAULT;
@ConfigAnnotations.FileComment
public static String _logRendererBufferEvent = IDebugSwitch.LOG_RENDERER_BUFFER_EVENT_DESC;
@ConfigAnnotations.Entry
public static LoggerMode logRendererBufferEvent = IDebugSwitch.LOG_RENDERER_BUFFER_EVENT_DEFAULT;
@ConfigAnnotations.FileComment
public static String _logRendererGLEvent = IDebugSwitch.LOG_RENDERER_GL_EVENT_DESC;
@ConfigAnnotations.Entry
public static LoggerMode logRendererGLEvent = IDebugSwitch.LOG_RENDERER_GL_EVENT_DEFAULT;
@ConfigAnnotations.FileComment
public static String _logFileReadWriteEvent = IDebugSwitch.LOG_FILE_READWRITE_EVENT_DESC;
@ConfigAnnotations.Entry
public static LoggerMode logFileReadWriteEvent = IDebugSwitch.LOG_FILE_READWRITE_EVENT_DEFAULT;
@ConfigAnnotations.FileComment
public static String _logFileSubDimEvent = IDebugSwitch.LOG_FILE_SUB_DIM_EVENT_DESC;
@ConfigAnnotations.Entry
public static LoggerMode logFileSubDimEvent = IDebugSwitch.LOG_FILE_SUB_DIM_EVENT_DEFAULT;
@ConfigAnnotations.FileComment
public static String _logNetworkEvent = IDebugSwitch.LOG_NETWORK_EVENT_DESC;
@ConfigAnnotations.Entry
public static LoggerMode logNetworkEvent = IDebugSwitch.LOG_NETWORK_EVENT_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,50 +0,0 @@
/*
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
* licensed under the GNU GPL 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 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.common.forge.LodForgeMethodCaller;
import com.seibel.lod.common.networking.NetworkInterface;
import com.seibel.lod.common.wrappers.DependencySetup;
import com.seibel.lod.common.wrappers.config.ConfigGui;
/**
* This is the common main class
* @author Ran
*/
public class LodCommonMain {
public static boolean forge = false;
public static boolean serverSided;
public static LodForgeMethodCaller forgeMethodCaller;
public static void startup(LodForgeMethodCaller caller, boolean serverSided) {
LodCommonMain.serverSided = serverSided;
if (caller != null) {
LodCommonMain.forge = true;
forgeMethodCaller = caller;
}
DependencySetup.createInitialBindings();
}
public static void initConfig() {
ConfigGui.init(Config.class);
}
}
@@ -1,49 +0,0 @@
/*
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
* licensed under the GNU GPL 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 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.forge;
import com.seibel.lod.common.wrappers.minecraft.MinecraftClientWrapper;
import net.minecraft.client.renderer.block.model.BakedQuad;
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.state.BlockState;
import java.util.List;
import java.util.Random;
/**
* used for calling methods that forge modified
* (forge modifies vanilla methods for some reason)
* @author Ran
*/
public interface LodForgeMethodCaller {
#if PRE_MC_1_19
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,49 +0,0 @@
/*
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
* licensed under the GNU GPL 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 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.networking;
import net.minecraft.client.Minecraft;
import net.minecraft.client.multiplayer.ClientPacketListener;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.server.network.ServerGamePacketListenerImpl;
/**
* This is packet handler for our mod
* It basically handles the packets sent from the server & client
*
* @author Ran
*/
public class NetworkHandler {
// If you need the response sender then tell me
// I'll add extra code to get the response sender
public static void receivePacketClient(Minecraft client, ClientPacketListener handler, FriendlyByteBuf buf) {
// 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
// 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,119 +0,0 @@
/*
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
* licensed under the GNU GPL 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 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.networking;
import com.seibel.lod.core.ModInfo;
import io.netty.buffer.Unpooled;
import net.minecraft.client.Minecraft;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.protocol.Packet;
import net.minecraft.network.protocol.game.ClientboundCustomPayloadPacket;
import net.minecraft.network.protocol.game.ServerboundCustomPayloadPacket;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ServerPlayer;
import java.util.Objects;
/**
* This class holds most of the networking code for the mod.
* @author Ran
*/
public class Networking {
public static final ResourceLocation resourceLocation_meow = new ResourceLocation("lod", "meow");
public static FriendlyByteBuf createNew() {
// TODO: Probably replace the Unpooled.buffer()
FriendlyByteBuf buf = new FriendlyByteBuf(Unpooled.buffer());
buf.writeInt(ModInfo.PROTOCOL_VERSION);
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.
*
* @param player the player to send the packet to
* @param buf the payload of the packet.
*/
public static void send(ServerPlayer player, FriendlyByteBuf buf) {
Objects.requireNonNull(player, "Server player entity cannot be null");
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));
}
/**
* Sends a packet to the connected server.
*
* @param buf the payload of the packet
* @throws IllegalStateException if the client is not connected to a server
*/
public static void send(FriendlyByteBuf buf) throws IllegalStateException {
// You cant send without a client player, so this is fine
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,57 +0,0 @@
/*
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
* licensed under the GNU GPL 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 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;
import com.seibel.lod.common.LodCommonMain;
import com.seibel.lod.common.wrappers.minecraft.MinecraftClientWrapper;
import com.seibel.lod.common.wrappers.minecraft.MinecraftRenderWrapper;
import com.seibel.lod.core.handlers.IReflectionHandler;
import com.seibel.lod.core.handlers.ReflectionHandler;
import com.seibel.lod.core.handlers.dependencyInjection.SingletonHandler;
import com.seibel.lod.core.wrapperInterfaces.IVersionConstants;
import com.seibel.lod.core.wrapperInterfaces.IWrapperFactory;
import com.seibel.lod.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
import com.seibel.lod.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
/**
* Binds all necessary dependencies, so we
* can access them in Core. <br>
* This needs to be called before any Core classes
* are loaded.
*
* @author James Seibel
* @author Ran
* @version 12-1-2021
*/
public class DependencySetup {
public static void createInitialBindings()
{
SingletonHandler.bind(IVersionConstants.class, VersionConstants.INSTANCE);
if (!LodCommonMain.serverSided)
{
SingletonHandler.bind(IMinecraftClientWrapper.class, MinecraftClientWrapper.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;
}
}
@@ -1,82 +0,0 @@
/*
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
* licensed under the GNU GPL 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 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;
import java.nio.FloatBuffer;
import com.mojang.math.Matrix4f;
import com.seibel.lod.common.wrappers.block.BlockPosWrapper;
import com.seibel.lod.core.enums.LodDirection;
import com.seibel.lod.core.objects.math.Mat4f;
import com.seibel.lod.core.wrapperInterfaces.block.AbstractBlockPosWrapper;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
/**
* This class converts to and from Minecraft objects (Ex: Matrix4f)
* and objects we created (Ex: Mat4f).
*
* @author James Seibel
* @version 11-20-2021
*/
public class McObjectConverter
{
/** 4x4 float matrix converter */
public static Mat4f Convert(Matrix4f mcMatrix)
{
FloatBuffer buffer = FloatBuffer.allocate(16);
mcMatrix.store(buffer);
Mat4f matrix = new Mat4f(buffer);
matrix.transpose();
return matrix;
}
static final Direction[] directions;
static final LodDirection[] lodDirections;
static {
LodDirection[] lodDirs = LodDirection.values();
directions = new Direction[lodDirs.length];
lodDirections = new LodDirection[lodDirs.length];
for (LodDirection lodDir : lodDirs) {
Direction dir = Enum.valueOf(Direction.class, lodDir.name());
if (dir == null) {
throw new IllegalArgumentException("Invalid direction on init mapping: " + lodDir);
}
directions[lodDir.ordinal()] = dir;
lodDirections[dir.ordinal()] = lodDir;
}
}
public static BlockPos Convert(AbstractBlockPosWrapper wrappedPos) {
return new BlockPos(wrappedPos.getX(),wrappedPos.getY(), wrappedPos.getZ());
}
public static Direction Convert(LodDirection lodDirection)
{
return directions[lodDirection.ordinal()];
}
public static LodDirection Convert(Direction direction)
{
return lodDirections[direction.ordinal()];
}
}
@@ -1,94 +0,0 @@
/*
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
* licensed under the GNU GPL 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 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;
import com.seibel.lod.core.builders.lodBuilding.LodBuilder;
import com.seibel.lod.core.objects.lod.LodDimension;
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.world.IWorldWrapper;
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;
/**
* This handles creating abstract wrapper objects.
*
* @author James Seibel
* @version 11-20-2021
*/
public class WrapperFactory implements IWrapperFactory
{
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
public AbstractChunkPosWrapper createChunkPos()
{
return new ChunkPosWrapper();
}
@Override
public AbstractChunkPosWrapper createChunkPos(long xAndZPositionCombined)
{
return new ChunkPosWrapper(xAndZPositionCombined);
}
@Override
public AbstractChunkPosWrapper createChunkPos(int x, int z)
{
return new ChunkPosWrapper(x, z);
}
@Override
public AbstractChunkPosWrapper createChunkPos(AbstractChunkPosWrapper newChunkPos)
{
return new ChunkPosWrapper(newChunkPos);
}
@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,47 +0,0 @@
/*
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
* licensed under the GNU GPL 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 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.block;
import java.util.concurrent.ConcurrentHashMap;
import com.seibel.lod.core.api.ApiShared;
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) {
if (!bs.getFluidState().isEmpty()) {
bs = bs.getFluidState().createLegacyBlock();
}
BlockDetailWrapper cache = map.get(bs);
if (cache != null) return cache;
cache = BlockDetailWrapper.make(bs, pos, getter);
//ApiShared.LOGGER.info("New blockDetail cache for {} to {} ", bs, cache);
BlockDetailWrapper cacheCAS = map.putIfAbsent(bs, cache);
return cacheCAS==null ? cache : cacheCAS;
}
}
@@ -1,350 +0,0 @@
/*
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
* licensed under the GNU GPL 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 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.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;
#if POST_MC_1_19
import net.minecraft.util.RandomSource;
#endif
/*-- WARN: This class should NEVER hold reference to anything large,
as this is never dealloc until the end of runtime!! --*/
public class BlockDetailWrapper extends IBlockDetailWrapper
{
private static final ILodConfigWrapperSingleton CONFIG = SingletonHandler.get(ILodConfigWrapperSingleton.class);
public static final int FLOWER_COLOR_SCALE = 5;
#if PRE_MC_1_19
public static final Random random = new Random(0);
#else
public static final RandomSource random = RandomSource.create();
#endif
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;
//boolean isShapeResolved = false;
//^ Shapes no longer lazy resolved due to memory leaks from needing
// to keep a reference to the block getter
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;
resolveShapes(getter, pos);
//ApiShared.LOGGER.info("Created BlockDetailWrapper for blockstate {} at {}", state, pos);
}
private BlockDetailWrapper() {
this.state = 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(LevelReader sampleGetter, BlockPos samplePos) {
//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];
}
}
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()) {
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;
}
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());
}
public String toString() {
return "BlockDetail{" + state + "}";
}
}
@@ -1,103 +0,0 @@
/*
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
* licensed under the GNU GPL 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 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.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;
}
}
@@ -1,52 +0,0 @@
/*
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
* licensed under the GNU GPL 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 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.block;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
/**
* For wrapping/utilizing around TextureAtlasSprite
* @author Ran
*/
public class TextureAtlasSpriteWrapper {
/**
* This code is from Minecraft Forge
* Which is licensed under the terms of GNU Lesser General Public License
* as published by the Free Software Foundation version 2.1
* of the License.
*
* The code has been modified to use TextureAtlasSprite
*/
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) {
x += sprite.animatedTexture.getFrameX(frameIndex) * sprite.width;
y += sprite.animatedTexture.getFrameY(frameIndex) * sprite.height;
}
return sprite.mainImage[0].getPixelRGBA(x, y);
#endif
}
}
@@ -1,217 +0,0 @@
/*
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
* licensed under the GNU GPL 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 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.block;
import com.seibel.lod.common.LodCommonMain;
import it.unimi.dsi.fastutil.objects.Object2ObjectArrayMap;
import net.minecraft.Util;
import net.minecraft.client.color.block.BlockTintCache;
import net.minecraft.client.renderer.BiomeColors;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Cursor3D;
import net.minecraft.core.Direction;
import net.minecraft.world.level.*;
import net.minecraft.world.level.biome.Biome;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.lighting.LevelLightEngine;
import net.minecraft.world.level.material.FluidState;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.Vec3;
import net.minecraft.world.phys.shapes.VoxelShape;
import org.jetbrains.annotations.Nullable;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Supplier;
import java.util.stream.Stream;
public class TintGetterOverrideFast implements BlockAndTintGetter {
LevelReader parent;
public TintGetterOverrideFast(LevelReader parent) {
this.parent = parent;
}
private Biome _getBiome(BlockPos pos) {
#if POST_MC_1_18_2
return parent.getBiome(pos).value();
#else
return parent.getBiome(pos);
#endif
}
@Override
public int getBlockTint(BlockPos blockPos, ColorResolver colorResolver) {
if (LodCommonMain.forgeMethodCaller != null) {
return LodCommonMain.forgeMethodCaller.colorResolverGetColor(colorResolver, _getBiome(blockPos),
blockPos.getX(), blockPos.getZ());
} else {
return colorResolver.getColor(_getBiome(blockPos), blockPos.getX(), blockPos.getZ());
}
}
@Override
public float getShade(Direction direction, boolean bl) {
return parent.getShade(direction, bl);
}
@Override
public LevelLightEngine getLightEngine() {
return parent.getLightEngine();
}
@Override
public int getBrightness(LightLayer lightLayer, BlockPos blockPos) {
return parent.getBrightness(lightLayer, blockPos);
}
@Override
public int getRawBrightness(BlockPos blockPos, int i) {
return parent.getRawBrightness(blockPos, i);
}
@Override
public boolean canSeeSky(BlockPos blockPos) {
return parent.canSeeSky(blockPos);
}
@Override
@Nullable
public BlockEntity getBlockEntity(BlockPos blockPos) {
return parent.getBlockEntity(blockPos);
}
@Override
public BlockState getBlockState(BlockPos blockPos) {
return parent.getBlockState(blockPos);
}
@Override
public FluidState getFluidState(BlockPos blockPos) {
return parent.getFluidState(blockPos);
}
@Override
public int getLightEmission(BlockPos blockPos) {
return parent.getLightEmission(blockPos);
}
@Override
public int getMaxLightLevel() {
return parent.getMaxLightLevel();
}
@Override
public Stream<BlockState> getBlockStates(AABB aABB) {
return parent.getBlockStates(aABB);
}
@Override
public BlockHitResult clip(ClipContext clipContext) {
return parent.clip(clipContext);
}
@Override
@Nullable
public BlockHitResult clipWithInteractionOverride(Vec3 vec3, Vec3 vec32, BlockPos blockPos, VoxelShape voxelShape, BlockState blockState) {
return parent.clipWithInteractionOverride(vec3, vec32, blockPos, voxelShape, blockState);
}
@Override
public double getBlockFloorHeight(VoxelShape voxelShape, Supplier<VoxelShape> supplier) {
return parent.getBlockFloorHeight(voxelShape, supplier);
}
@Override
public double getBlockFloorHeight(BlockPos 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
public int getHeight() {
return parent.getHeight();
}
@Override
public int getMinBuildHeight() {
return parent.getMinBuildHeight();
}
@Override
public int getSectionsCount() {
return parent.getSectionsCount();
}
@Override
public int getMinSection() {
return parent.getMinSection();
}
@Override
public int getMaxSection() {
return parent.getMaxSection();
}
@Override
public boolean isOutsideBuildHeight(BlockPos blockPos) {
return parent.isOutsideBuildHeight(blockPos);
}
@Override
public boolean isOutsideBuildHeight(int i) {
return parent.isOutsideBuildHeight(i);
}
@Override
public int getSectionIndex(int i) {
return parent.getSectionIndex(i);
}
@Override
public int getSectionIndexFromSectionY(int i) {
return parent.getSectionIndexFromSectionY(i);
}
@Override
public int getSectionYFromSectionIndex(int i) {
return parent.getSectionYFromSectionIndex(i);
}
#endif
}
@@ -1,241 +0,0 @@
/*
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
* licensed under the GNU GPL 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 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.block;
import com.seibel.lod.common.LodCommonMain;
import it.unimi.dsi.fastutil.objects.Object2ObjectArrayMap;
import net.minecraft.Util;
import net.minecraft.client.color.block.BlockTintCache;
import net.minecraft.client.renderer.BiomeColors;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Cursor3D;
import net.minecraft.core.Direction;
import net.minecraft.world.level.*;
import net.minecraft.world.level.biome.Biome;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.lighting.LevelLightEngine;
import net.minecraft.world.level.material.FluidState;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.Vec3;
import net.minecraft.world.phys.shapes.VoxelShape;
import org.jetbrains.annotations.Nullable;
import java.util.Optional;
import java.util.function.Supplier;
import java.util.stream.Stream;
public class TintGetterOverrideSmooth implements BlockAndTintGetter {
LevelReader parent;
public int smoothingRange;
public TintGetterOverrideSmooth(LevelReader parent, int smoothingRange) {
this.parent = parent;
this.smoothingRange = smoothingRange;
}
private Biome _getBiome(BlockPos pos) {
#if POST_MC_1_18_2
return parent.getBiome(pos).value();
#else
return parent.getBiome(pos);
#endif
}
public int calculateBlockTint(BlockPos blockPos, ColorResolver colorResolver)
{
int i = smoothingRange;
if (i == 0)
return colorResolver.getColor(_getBiome(blockPos), blockPos.getX(), blockPos.getZ());
int j = (i * 2 + 1) * (i * 2 + 1);
int k = 0;
int l = 0;
int m = 0;
Cursor3D cursor3D = new Cursor3D(blockPos.getX() - i, blockPos.getY(), blockPos.getZ() - i, blockPos.getX() + i, blockPos.getY(), blockPos.getZ() + i);
BlockPos.MutableBlockPos mutableBlockPos = new BlockPos.MutableBlockPos();
while (cursor3D.advance())
{
mutableBlockPos.set(cursor3D.nextX(), cursor3D.nextY(), cursor3D.nextZ());
int n;
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 int getBlockTint(BlockPos blockPos, ColorResolver colorResolver) {
return calculateBlockTint(blockPos, colorResolver);
}
@Override
public float getShade(Direction direction, boolean bl) {
return parent.getShade(direction, bl);
}
@Override
public LevelLightEngine getLightEngine() {
return parent.getLightEngine();
}
@Override
public int getBrightness(LightLayer lightLayer, BlockPos blockPos) {
return parent.getBrightness(lightLayer, blockPos);
}
@Override
public int getRawBrightness(BlockPos blockPos, int i) {
return parent.getRawBrightness(blockPos, i);
}
@Override
public boolean canSeeSky(BlockPos blockPos) {
return parent.canSeeSky(blockPos);
}
@Override
@Nullable
public BlockEntity getBlockEntity(BlockPos blockPos) {
return parent.getBlockEntity(blockPos);
}
@Override
public BlockState getBlockState(BlockPos blockPos) {
return parent.getBlockState(blockPos);
}
@Override
public FluidState getFluidState(BlockPos blockPos) {
return parent.getFluidState(blockPos);
}
@Override
public int getLightEmission(BlockPos blockPos) {
return parent.getLightEmission(blockPos);
}
@Override
public int getMaxLightLevel() {
return parent.getMaxLightLevel();
}
@Override
public Stream<BlockState> getBlockStates(AABB aABB) {
return parent.getBlockStates(aABB);
}
@Override
public BlockHitResult clip(ClipContext clipContext) {
return parent.clip(clipContext);
}
@Override
@Nullable
public BlockHitResult clipWithInteractionOverride(Vec3 vec3, Vec3 vec32, BlockPos blockPos, VoxelShape voxelShape, BlockState blockState) {
return parent.clipWithInteractionOverride(vec3, vec32, blockPos, voxelShape, blockState);
}
@Override
public double getBlockFloorHeight(VoxelShape voxelShape, Supplier<VoxelShape> supplier) {
return parent.getBlockFloorHeight(voxelShape, supplier);
}
@Override
public double getBlockFloorHeight(BlockPos 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
public int getHeight() {
return parent.getHeight();
}
@Override
public int getMinBuildHeight() {
return parent.getMinBuildHeight();
}
@Override
public int getSectionsCount() {
return parent.getSectionsCount();
}
@Override
public int getMinSection() {
return parent.getMinSection();
}
@Override
public int getMaxSection() {
return parent.getMaxSection();
}
@Override
public boolean isOutsideBuildHeight(BlockPos blockPos) {
return parent.isOutsideBuildHeight(blockPos);
}
@Override
public boolean isOutsideBuildHeight(int i) {
return parent.isOutsideBuildHeight(i);
}
@Override
public int getSectionIndex(int i) {
return parent.getSectionIndex(i);
}
@Override
public int getSectionIndexFromSectionY(int i) {
return parent.getSectionIndexFromSectionY(i);
}
@Override
public int getSectionYFromSectionIndex(int i) {
return parent.getSectionYFromSectionIndex(i);
}
#endif
}
@@ -1,159 +0,0 @@
/*
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
* licensed under the GNU GPL 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 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.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
#if PRE_MC_1_17_1
BlockPos blockPos = chunkPos.getWorldPosition();
#else
BlockPos blockPos = chunkPos.getMiddleBlockPosition(0);
#endif
return new BlockPosWrapper(blockPos.getX(), blockPos.getY(), blockPos.getZ());
}
}
@@ -1,251 +0,0 @@
/*
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
* licensed under the GNU GPL 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 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.chunk;
import com.seibel.lod.common.wrappers.block.BlockDetailWrapper;
import com.seibel.lod.core.enums.LodDirection;
import com.seibel.lod.core.util.LevelPosUtil;
import com.seibel.lod.core.util.LodUtil;
import com.seibel.lod.core.wrapperInterfaces.block.IBlockDetailWrapper;
import com.seibel.lod.core.wrapperInterfaces.chunk.IChunkWrapper;
import com.seibel.lod.core.wrapperInterfaces.world.IBiomeWrapper;
import com.seibel.lod.common.wrappers.WrapperUtil;
import com.seibel.lod.common.wrappers.block.BlockDetailMap;
import com.seibel.lod.common.wrappers.world.BiomeWrapper;
import com.seibel.lod.common.wrappers.worldGeneration.mimicObject.LightedWorldGenRegion;
import net.minecraft.core.BlockPos;
#if POST_MC_1_17_1
import net.minecraft.core.QuartPos;
#endif
import net.minecraft.world.level.LevelReader;
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.ChunkStatus;
import net.minecraft.world.level.chunk.LevelChunk;
import net.minecraft.world.level.levelgen.Heightmap;
/**
*
* @author James Seibel
* @version 3-5-2022
*/
public class ChunkWrapper implements IChunkWrapper
{
private final ChunkAccess chunk;
private final LevelReader lightSource;
public ChunkWrapper(ChunkAccess chunk, LevelReader lightSource)
{
this.chunk = chunk;
this.lightSource = lightSource;
}
@Override
public int getHeight(){
#if PRE_MC_1_17_1
return 255;
#else
return chunk.getHeight();
#endif
}
@Override
public int getMinBuildHeight()
{
#if PRE_MC_1_17_1
return 0;
#else
return chunk.getMinBuildHeight();
#endif
}
@Override
public int getMaxBuildHeight()
{
return chunk.getMaxBuildHeight();
}
@Override
public int getHeightMapValue(int xRel, int zRel)
{
return chunk.getOrCreateHeightmapUnprimed(WrapperUtil.DEFAULT_HEIGHTMAP).getFirstAvailable(xRel, zRel);
}
@Override
public IBiomeWrapper getBiome(int x, int y, int z)
{
#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(
QuartPos.fromBlock(x), QuartPos.fromBlock(y), QuartPos.fromBlock(z)));
#else
return BiomeWrapper.getBiomeWrapper(chunk.getNoiseBiome(
QuartPos.fromBlock(x), QuartPos.fromBlock(y), QuartPos.fromBlock(z)).value());
#endif
}
@Override
public IBlockDetailWrapper getBlockDetail(int x, int y, int z) {
BlockPos pos = new BlockPos(x,y,z);
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() {
return chunk;
}
@Override
public int getChunkPosX(){
return chunk.getPos().x;
}
@Override
public int getChunkPosZ(){
return chunk.getPos().z;
}
@Override
public int getRegionPosX(){
return LevelPosUtil.convert(LodUtil.CHUNK_DETAIL_LEVEL, chunk.getPos().x, LodUtil.REGION_DETAIL_LEVEL);
}
@Override
public int getRegionPosZ(){
return LevelPosUtil.convert(LodUtil.CHUNK_DETAIL_LEVEL, chunk.getPos().z, LodUtil.REGION_DETAIL_LEVEL);
}
@Override
public int getMaxY(int x, int z) {
return chunk.getHeight(Heightmap.Types.WORLD_SURFACE, Math.floorMod(x, 16), Math.floorMod(z, 16));
}
@Override
public int getMaxX(){
return chunk.getPos().getMaxBlockX();
}
@Override
public int getMaxZ(){
return chunk.getPos().getMaxBlockZ();
}
@Override
public int getMinX(){
return chunk.getPos().getMinBlockX();
}
@Override
public int getMinZ() {
return chunk.getPos().getMinBlockZ();
}
@Override
public long getLongChunkPos() {
return chunk.getPos().toLong();
}
@Override
public boolean isLightCorrect(){
#if PRE_MC_1_18_1
return true;
#else
if (chunk instanceof LevelChunk) {
return ((LevelChunk) chunk).isClientLightReady();
}
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
public int getBlockLight(int x, int y, int z) {
if (lightSource == null) return -1;
return lightSource.getBrightness(LightLayer.BLOCK, new BlockPos(x,y,z));
}
@Override
public int getSkyLight(int x, int y, int z) {
if (lightSource == null) return -1;
return lightSource.getBrightness(LightLayer.SKY, new BlockPos(x,y,z));
}
@Override
public boolean doesNearbyChunksExist() {
if (lightSource instanceof LightedWorldGenRegion) return true;
for (int dx = -1; dx <= 1; dx++) {
for (int dz = -1; dz <= 1; dz++) {
if (dx==0 && dz==0) continue;
if (lightSource.getChunk(dx+getChunkPosX(), dz+getChunkPosZ(), ChunkStatus.BIOMES, false) == null) return false;
}
}
return true;
}
public LevelReader getColorResolver()
{
return lightSource;
}
@Override
public String toString() {
return chunk.getClass().getSimpleName() + chunk.getPos();
}
}
@@ -1,817 +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;
#if PRE_MC_1_19
import net.minecraft.network.chat.TextComponent;
import net.minecraft.network.chat.TranslatableComponent;
#endif
import net.minecraft.client.resources.language.I18n; // translation
#if POST_MC_1_17_1
import net.minecraft.client.gui.narration.NarratableEntry;
#endif
/**
* 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
*
* REMOVED IN a1.7
*
* @author coolGi
* @version 1-14-2022
*/
@Deprecated
@SuppressWarnings("unchecked")
public abstract class ConfigGui
{
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;
#if PRE_MC_1_19
TranslatableComponent name;
#else
Component name;
#endif
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(""))
#if PRE_MC_1_19
info.name = new TranslatableComponent(entry.name());
#else
info.name = Component.translatable(entry.name());
#endif
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
#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
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());
#if PRE_MC_1_19
Function<Object, Component> func = value -> new TranslatableComponent(MOD_NAME + ".config." + "enum." + fieldClass.getSimpleName() + "." + info.value.toString());
#else
Function<Object, Component> func = value -> Component.translatable(MOD_NAME + ".config." + "enum." + fieldClass.getSimpleName() + "." + info.value.toString());
#endif
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(""))
#if PRE_MC_1_19
info.name = new TranslatableComponent(screenEntry.name());
#else
info.name = Component.translatable(screenEntry.name());
#endif
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;
#if PRE_MC_1_19
info.error = inLimits ? null : new AbstractMap.SimpleEntry<>(editBox, new TextComponent(value.doubleValue() < minValue ?
#else
info.error = inLimits ? null : new AbstractMap.SimpleEntry<>(editBox, Component.translatable(value.doubleValue() < minValue ?
#endif
"§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 (!configFilePath.getParent().toFile().exists())
Files.createDirectory(configFilePath.getParent());
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.set("_version", 1);
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.set("_version", 1);
// 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()) {
try {
info.value = config.getEnum(itemPath, info.varClass);
} catch (IllegalArgumentException ignored) {
return;
}
}
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)
{
#if PRE_MC_1_19
super(new TranslatableComponent(
#else
super(Component.translatable(
#endif
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);
}
// 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)
loadFromFile();
addBtn(new Button(this.width / 2 - 154, this.height - 28, 150, 20, CommonComponents.GUI_CANCEL, button -> {
loadFromFile();
Objects.requireNonNull(minecraft).setScreen(parent);
}));
Button done = addBtn(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)
{
#if PRE_MC_1_19
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 -> {
#else
Component name = (info.name == null ? Component.translatable(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, Component.translatable("Reset").withStyle(ChatFormatting.RED), (button -> {
#endif
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())
#if PRE_MC_1_19
widget.setValue(value -> new TranslatableComponent(translationPrefix + "enum." + info.field.getType().getSimpleName() + "." + info.value.toString()));
#else
widget.setValue(value -> Component.translatable(translationPrefix + "enum." + info.field.getType().getSimpleName() + "." + info.value.toString()));
#endif
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);
#if PRE_MC_1_19
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 -> {
#else
resetButton.setMessage(Component.translatable("R").withStyle(ChatFormatting.RED));
Button cycleButton = new Button(this.width - 185, 0, 20, 20, Component.translatable(String.valueOf(info.index)).withStyle(ChatFormatting.GOLD), (button -> {
#endif
((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);
#if PRE_MC_1_19
TranslatableComponent name = new TranslatableComponent(this.translationPrefix + (info.category.isEmpty() ? "" : info.category + ".") + info.field.getName());
#else
Component name = Component.translatable(this.translationPrefix + (info.category.isEmpty() ? "" : info.category + ".") + info.field.getName());
#endif
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"))
#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);
}
}
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
}
}
@@ -1,966 +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 getOverdrawOffset() {
return Config.Client.Graphics.AdvancedGraphics.overdrawOffset;
}
@Override
public void setOverdrawOffset(int newOverdrawOffset) {
ConfigGui.editSingleOption.getEntry("client.graphics.advancedGraphics.overdrawOffset").value = newOverdrawOffset;
ConfigGui.editSingleOption.saveOption("client.graphics.advancedGraphics.overdrawOffset");
}
/*
@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");
}
@Override
public boolean getEnableCaveCulling() {
return Config.Client.Graphics.AdvancedGraphics.enableCaveCulling;
}
@Override
public void setEnableCaveCulling(boolean newEnableCaveCulling) {
ConfigGui.editSingleOption.getEntry("client.graphics.advancedGraphics.enableCaveCulling").value = newEnableCaveCulling;
ConfigGui.editSingleOption.saveOption("client.graphics.advancedGraphics.enableCaveCulling");
}
@Override
public int getCaveCullingHeight() {
return Config.Client.Graphics.AdvancedGraphics.caveCullingHeight;
}
@Override
public void setCaveCullingHeight(int newCaveCullingHeight) {
ConfigGui.editSingleOption.getEntry("client.graphics.advancedGraphics.caveCullingHeight").value = newCaveCullingHeight;
ConfigGui.editSingleOption.saveOption("client.graphics.advancedGraphics.caveCullingHeight");
}
@Override
public int getEarthCurveRatio()
{
return (int) ConfigGui.editSingleOption.getEntry("client.graphics.advancedGraphics.earthCurveRatio").value;
}
@Override
public void setEarthCurveRatio(int newEarthCurveRatio)
{
if (newEarthCurveRatio < 50) newEarthCurveRatio = 0;
ConfigGui.editSingleOption.getEntry("client.graphics.advancedGraphics.earthCurveRatio").value = newEarthCurveRatio;
ConfigGui.editSingleOption.saveOption("client.graphics.advancedGraphics.earthCurveRatio");
}
}
}
//========================//
// 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 double getNumberOfWorldGenerationThreads()
{
return Config.Client.Advanced.Threading.numberOfWorldGenerationThreads;
}
@Override
public void setNumberOfWorldGenerationThreads(double 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
{
public final IDebugSwitch debugSwitch;
@Override
public IDebugSwitch debugSwitch()
{
return debugSwitch;
}
/* RendererType:
* DEFAULT
* DEBUG
* DISABLED
* */
@Override
public RendererType getRendererType() {
return (RendererType) ConfigGui.editSingleOption.getEntry("client.advanced.debugging.rendererType").value;
}
@Override
public void setRendererType(RendererType newRenderType) {
ConfigGui.editSingleOption.getEntry("client.advanced.debugging.rendererType").value = newRenderType;
ConfigGui.editSingleOption.saveOption("client.advanced.debugging.rendererType");
}
@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 Debugging()
{
debugSwitch = new DebugSwitch();
}
public static class DebugSwitch implements IDebugSwitch {
/* The logging switches available:
* WorldGenEvent
* WorldGenPerformance
* WorldGenLoadEvent
* LodBuilderEvent
* RendererBufferEvent
* RendererGLEvent
* FileReadWriteEvent
* FileSubDimEvent
* NetworkEvent //NOT IMPL YET
*/
@Override
public LoggerMode getLogWorldGenEvent() {
return (LoggerMode) ConfigGui.editSingleOption.getEntry("client.advanced.debugging.debugSwitch.logWorldGenEvent").value;
}
@Override
public void setLogWorldGenEvent(LoggerMode newLogWorldGenEvent) {
ConfigGui.editSingleOption.getEntry("client.advanced.debugging.debugSwitch.logWorldGenEvent").value = newLogWorldGenEvent;
ConfigGui.editSingleOption.saveOption("client.advanced.debugging.debugSwitch.logWorldGenEvent");
}
@Override
public LoggerMode getLogWorldGenPerformance() {
return (LoggerMode) ConfigGui.editSingleOption.getEntry("client.advanced.debugging.debugSwitch.logWorldGenPerformance").value;
}
@Override
public void setLogWorldGenPerformance(LoggerMode newLogWorldGenPerformance) {
ConfigGui.editSingleOption.getEntry("client.advanced.debugging.debugSwitch.logWorldGenPerformance").value = newLogWorldGenPerformance;
ConfigGui.editSingleOption.saveOption("client.advanced.debugging.debugSwitch.logWorldGenPerformance");
}
@Override
public LoggerMode getLogWorldGenLoadEvent() {
return (LoggerMode) ConfigGui.editSingleOption.getEntry("client.advanced.debugging.debugSwitch.logWorldGenLoadEvent").value;
}
@Override
public void setLogWorldGenLoadEvent(LoggerMode newLogWorldGenLoadEvent) {
ConfigGui.editSingleOption.getEntry("client.advanced.debugging.debugSwitch.logWorldGenLoadEvent").value = newLogWorldGenLoadEvent;
ConfigGui.editSingleOption.saveOption("client.advanced.debugging.debugSwitch.logWorldGenLoadEvent");
}
@Override
public LoggerMode getLogLodBuilderEvent() {
return (LoggerMode) ConfigGui.editSingleOption.getEntry("client.advanced.debugging.debugSwitch.logLodBuilderEvent").value;
}
@Override
public void setLogLodBuilderEvent(LoggerMode newLogLodBuilderEvent) {
ConfigGui.editSingleOption.getEntry("client.advanced.debugging.debugSwitch.logLodBuilderEvent").value = newLogLodBuilderEvent;
ConfigGui.editSingleOption.saveOption("client.advanced.debugging.debugSwitch.logLodBuilderEvent");
}
@Override
public LoggerMode getLogRendererBufferEvent() {
return (LoggerMode) ConfigGui.editSingleOption.getEntry("client.advanced.debugging.debugSwitch.logRendererBufferEvent").value;
}
@Override
public void setLogRendererBufferEvent(LoggerMode newLogRendererBufferEvent) {
ConfigGui.editSingleOption.getEntry("client.advanced.debugging.debugSwitch.logRendererBufferEvent").value = newLogRendererBufferEvent;
ConfigGui.editSingleOption.saveOption("client.advanced.debugging.debugSwitch.logRendererBufferEvent");
}
@Override
public LoggerMode getLogRendererGLEvent() {
return (LoggerMode) ConfigGui.editSingleOption.getEntry("client.advanced.debugging.debugSwitch.logRendererGLEvent").value;
}
@Override
public void setLogRendererGLEvent(LoggerMode newLogRendererGLEvent) {
ConfigGui.editSingleOption.getEntry("client.advanced.debugging.debugSwitch.logRendererGLEvent").value = newLogRendererGLEvent;
ConfigGui.editSingleOption.saveOption("client.advanced.debugging.debugSwitch.logRendererGLEvent");
}
@Override
public LoggerMode getLogFileReadWriteEvent() {
return (LoggerMode) ConfigGui.editSingleOption.getEntry("client.advanced.debugging.debugSwitch.logFileReadWriteEvent").value;
}
@Override
public void setLogFileReadWriteEvent(LoggerMode newLogFileReadWriteEvent) {
ConfigGui.editSingleOption.getEntry("client.advanced.debugging.debugSwitch.logFileReadWriteEvent").value = newLogFileReadWriteEvent;
ConfigGui.editSingleOption.saveOption("client.advanced.debugging.debugSwitch.logFileReadWriteEvent");
}
@Override
public LoggerMode getLogFileSubDimEvent() {
return (LoggerMode) ConfigGui.editSingleOption.getEntry("client.advanced.debugging.debugSwitch.logFileSubDimEvent").value;
}
@Override
public void setLogFileSubDimEvent(LoggerMode newLogFileSubDimEvent) {
ConfigGui.editSingleOption.getEntry("client.advanced.debugging.debugSwitch.logFileSubDimEvent").value = newLogFileSubDimEvent;
ConfigGui.editSingleOption.saveOption("client.advanced.debugging.debugSwitch.logFileSubDimEvent");
}
@Override
public LoggerMode getLogNetworkEvent() {
return (LoggerMode) ConfigGui.editSingleOption.getEntry("client.advanced.debugging.debugSwitch.logNetworkEvent").value;
}
@Override
public void setLogNetworkEvent(LoggerMode newLogNetworkEvent) {
ConfigGui.editSingleOption.getEntry("client.advanced.debugging.debugSwitch.logNetworkEvent").value = newLogNetworkEvent;
ConfigGui.editSingleOption.saveOption("client.advanced.debugging.debugSwitch.logNetworkEvent");
}
}
}
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");
}
}
@Override
public boolean getLodOnlyMode() {
return Config.Client.Advanced.lodOnlyMode;
}
@Override
public void setLodOnlyMode(boolean newLodOnlyMode) {
ConfigGui.editSingleOption.getEntry("client.advanced.buffers.lodOnlyMode").value = newLodOnlyMode;
ConfigGui.editSingleOption.saveOption("client.advanced.buffers.lodOnlyMode");
}
}
}
}
@@ -1,72 +0,0 @@
/*
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
* licensed under the GNU GPL 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 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.config;
import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.components.ImageButton;
import net.minecraft.client.renderer.GameRenderer;
import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceLocation;
/**
* Creates a button with a texture on it
*/
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) {
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) {
super(x, y, width, height, u, v, hoveredVOffset, texture, textureWidth, textureHeight, 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, Component text) {
super(x, y, width, height, u, v, hoveredVOffset, texture, textureWidth, textureHeight, pressAction, text);
}
public TexturedButtonWidget(int x, int y, int width, int height, int u, int v, int hoveredVOffset, ResourceLocation texture, int textureWidth, int textureHeight, OnPress pressAction, OnTooltip tooltipSupplier, Component text) {
super(x, y, width, height, u, v, hoveredVOffset, texture, textureWidth, textureHeight, pressAction, tooltipSupplier, text);
}
@Override
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.setShaderTexture(0, WIDGETS_LOCATION);
RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, this.alpha);
#endif
int i = this.getYImage(this.isHovered);
RenderSystem.enableBlend();
RenderSystem.defaultBlendFunc();
RenderSystem.enableDepthTest();
this.blit(matrices, this.x, this.y, 0, 46 + i * 20, this.width / 2, this.height);
this.blit(matrices, this.x + this.width / 2, this.y, 200 - this.width / 2, 46 + i * 20, this.width / 2, this.height);
super.renderButton(matrices, mouseX, mouseY, delta);
}
}
@@ -1,398 +0,0 @@
/*
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
* licensed under the GNU GPL 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 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.minecraft;
import java.awt.Color;
import java.io.File;
import java.util.ArrayList;
import com.mojang.blaze3d.platform.NativeImage;
import com.mojang.blaze3d.platform.Window;
import com.seibel.lod.core.ModInfo;
import com.seibel.lod.core.api.ApiShared;
import com.seibel.lod.core.enums.LodDirection;
import com.seibel.lod.core.util.LodUtil;
import com.seibel.lod.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
import com.seibel.lod.core.wrapperInterfaces.minecraft.IProfilerWrapper;
import com.seibel.lod.core.wrapperInterfaces.misc.ILightMapWrapper;
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.block.BlockPosWrapper;
import com.seibel.lod.common.wrappers.chunk.ChunkPosWrapper;
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.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.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.server.IntegratedServer;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
#if PRE_MC_1_19
import net.minecraft.network.chat.TextComponent;
#endif
import net.minecraft.network.chat.Component;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.ChunkPos;
import net.minecraft.world.level.LightLayer;
import net.minecraft.world.level.dimension.DimensionType;
import org.jetbrains.annotations.Nullable;
/**
* A singleton that wraps the Minecraft object.
*
* @author James Seibel
* @version 3-5-2022
*/
public class MinecraftClientWrapper implements IMinecraftClientWrapper
{
public static final MinecraftClientWrapper INSTANCE = new MinecraftClientWrapper();
public final Minecraft mc = Minecraft.getInstance();
/**
* The lightmap for the current:
* Time, dimension, brightness setting, etc.
*/
private NativeImage lightMap = null;
private ProfilerWrapper profilerWrapper;
private MinecraftClientWrapper()
{
}
//================//
// helper methods //
//================//
/**
* This should be called at the beginning of every frame to
* clear any Minecraft data that becomes out of date after a frame. <br> <br>
* <p>
* LightMaps and other time sensitive objects fall in this category. <br> <br>
* <p>
* This doesn't affect OpenGL objects in any way.
*/
@Override
public void clearFrameObjectCache()
{
lightMap = null;
}
//=================//
// method wrappers //
//=================//
@Override
public float getShade(LodDirection lodDirection) {
if (mc.level != null)
{
Direction mcDir = McObjectConverter.Convert(lodDirection);
return mc.level.getShade(mcDir, true);
}
else return 0.0f;
}
@Override
public boolean hasSinglePlayerServer()
{
return mc.hasSingleplayerServer();
}
@Override
public String getCurrentServerName()
{
return mc.getCurrentServer().name;
}
@Override
public String getCurrentServerIp()
{
return mc.getCurrentServer().ip;
}
@Override
public String getCurrentServerVersion()
{
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));
}
//=============//
// Simple gets //
//=============//
public LocalPlayer getPlayer()
{
return mc.player;
}
@Override
public boolean playerExists()
{
return mc.player != null;
}
@Override
public BlockPosWrapper getPlayerBlockPos()
{
BlockPos playerPos = getPlayer().blockPosition();
return new BlockPosWrapper(playerPos.getX(), playerPos.getY(), playerPos.getZ());
}
@Override
public ChunkPosWrapper getPlayerChunkPos()
{
#if PRE_MC_1_17_1
ChunkPos playerPos = new ChunkPos(getPlayer().blockPosition());
#else
ChunkPos playerPos = getPlayer().chunkPosition();
#endif
return new ChunkPosWrapper(playerPos.x, playerPos.z);
}
public Options getOptions()
{
return mc.options;
}
public ModelManager 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
@Override
public IWorldWrapper getWrappedClientWorld()
{
return WorldWrapper.getWorldWrapper(mc.level);
}
@Override
public File getGameDirectory()
{
return mc.gameDirectory;
}
@Override
public IProfilerWrapper getProfiler()
{
if (profilerWrapper == null)
profilerWrapper = new ProfilerWrapper(mc.getProfiler());
else if (mc.getProfiler() != profilerWrapper.profiler)
profilerWrapper.profiler = mc.getProfiler();
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;
}
@Override
public int getPlayerSkylight() {
if (mc.level == null) return -1;
if (mc.player == null) return -1;
if (mc.player.blockPosition() == null) return -1;
return mc.level.getBrightness(LightLayer.SKY, mc.player.blockPosition());
}
public ServerData getCurrentServer()
{
return mc.getCurrentServer();
}
public LevelRenderer getLevelRenderer()
{
return mc.levelRenderer;
}
/** Returns all worlds available to the server */
@Override
public ArrayList<IWorldWrapper> getAllServerWorlds()
{
ArrayList<IWorldWrapper> worlds = new ArrayList<IWorldWrapper>();
Iterable<ServerLevel> serverWorlds = mc.getSingleplayerServer().getAllLevels();
for (ServerLevel world : serverWorlds)
{
worlds.add(WorldWrapper.getWorldWrapper(world));
}
return worlds;
}
@Override
public void sendChatMessage(String string)
{
#if PRE_MC_1_19
getPlayer().sendMessage(new TextComponent(string), getPlayer().getUUID());
#else
getPlayer().sendSystemMessage(Component.translatable(string));
#endif
}
/**
* Crashes Minecraft, displaying the given errorMessage <br> <br>
* In the following format: <br>
*
* The game crashed whilst <strong>errorMessage</strong> <br>
* Error: <strong>ExceptionClass: exceptionErrorMessage</strong> <br>
* Exit Code: -1 <br>
*/
@Override
public void crashMinecraft(String errorMessage, Throwable exception)
{
ApiShared.LOGGER.error(ModInfo.READABLE_NAME + " had the following error: [" + errorMessage + "]. Crashing Minecraft...");
CrashReport report = new CrashReport(errorMessage, exception);
Minecraft.crash(report);
}
}
@@ -1,302 +0,0 @@
/*
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
* licensed under the GNU GPL 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 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.minecraft;
import java.awt.Color;
import java.util.Collection;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.stream.Collectors;
import com.mojang.blaze3d.pipeline.RenderTarget;
import com.mojang.blaze3d.platform.NativeImage;
import com.mojang.blaze3d.systems.RenderSystem;
import com.seibel.lod.common.wrappers.misc.LightMapWrapper;
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.util.LodUtil;
import com.seibel.lod.core.wrapperInterfaces.misc.ILightMapWrapper;
import net.minecraft.client.renderer.LightTexture;
import com.mojang.math.Vector3f;
import com.seibel.lod.core.objects.math.Mat4f;
import com.seibel.lod.core.objects.math.Vec3d;
import com.seibel.lod.core.objects.math.Vec3f;
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.modAccessor.IOptifineAccessor;
import com.seibel.lod.core.wrapperInterfaces.modAccessor.ISodiumAccessor;
import com.seibel.lod.common.wrappers.McObjectConverter;
import com.seibel.lod.common.wrappers.WrapperFactory;
import com.seibel.lod.common.wrappers.block.BlockPosWrapper;
import net.minecraft.client.Camera;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.FogRenderer;
import net.minecraft.client.renderer.GameRenderer;
import net.minecraft.client.renderer.LevelRenderer;
import net.minecraft.core.BlockPos;
import net.minecraft.world.effect.MobEffects;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.LivingEntity;
#if PRE_MC_1_17_1
import net.minecraft.tags.FluidTags;
import net.minecraft.world.level.material.FluidState;
#else
import net.minecraft.world.level.material.FogType;
#endif
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
import org.lwjgl.opengl.GL15;
/**
* A singleton that contains everything
* related to rendering in Minecraft.
*
* @author James Seibel
* @version 12-12-2021
*/
public class MinecraftRenderWrapper implements IMinecraftRenderWrapper
{
public static final MinecraftRenderWrapper INSTANCE = new MinecraftRenderWrapper();
private static final Minecraft MC = Minecraft.getInstance();
private static final GameRenderer GAME_RENDERER = MC.gameRenderer;
private static final IWrapperFactory FACTORY = WrapperFactory.INSTANCE;
public LightMapWrapper lightmap = null;
@Override
public Vec3f getLookAtVector()
{
Camera camera = GAME_RENDERER.getMainCamera();
Vector3f cameraDir = camera.getLookVector();
return new Vec3f(cameraDir.x(), cameraDir.y(), cameraDir.z());
}
@Override
public AbstractBlockPosWrapper getCameraBlockPosition()
{
Camera camera = GAME_RENDERER.getMainCamera();
BlockPos blockPos = camera.getBlockPosition();
return new BlockPosWrapper(blockPos.getX(), blockPos.getY(), blockPos.getZ());
}
@Override
public boolean playerHasBlindnessEffect()
{
return MC.player.getActiveEffectsMap().get(MobEffects.BLINDNESS) != null;
}
@Override
public Vec3d getCameraExactPosition()
{
Camera camera = GAME_RENDERER.getMainCamera();
Vec3 projectedView = camera.getPosition();
return new Vec3d(projectedView.x, projectedView.y, projectedView.z);
}
@Override
public Mat4f getDefaultProjectionMatrix(float partialTicks)
{
#if PRE_MC_1_17_1
return McObjectConverter.Convert(GAME_RENDERER.getProjectionMatrix(GAME_RENDERER.getMainCamera(), partialTicks, true));
#else
return McObjectConverter.Convert(GAME_RENDERER.getProjectionMatrix(GAME_RENDERER.getFov(GAME_RENDERER.getMainCamera(), partialTicks, true)));
#endif
}
@Override
public double getGamma()
{
#if PRE_MC_1_19
return MC.options.gamma;
#else
return MC.options.gamma().get();
#endif
}
@Override
public Color getFogColor(float partialTicks) {
#if PRE_MC_1_17_1
float[] colorValues = new float[4];
GL15.glGetFloatv(GL15.GL_FOG_COLOR, colorValues);
#else
FogRenderer.setupColor(GAME_RENDERER.getMainCamera(), partialTicks, MC.level, 1, GAME_RENDERER.getDarkenWorldAmount(partialTicks));
float[] colorValues = RenderSystem.getShaderFogColor();
#endif
return new Color(colorValues[0], colorValues[1], colorValues[2], colorValues[3]);
}
// getSpecialFogColor() is the same as getFogColor()
@Override
public Color getSkyColor() {
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());
#endif
return new Color((float) colorValues.x, (float) colorValues.y, (float) colorValues.z);
} else
return new Color(0, 0, 0);
}
@Override
public double getFov(float partialTicks)
{
return GAME_RENDERER.getFov(GAME_RENDERER.getMainCamera(), partialTicks, true);
}
/** Measured in chunks */
@Override
public int getRenderDistance()
{
#if PRE_MC_1_18_1
//FIXME: How to resolve this?
return MC.options.renderDistance;
#else
return MC.options.getEffectiveRenderDistance();
#endif
}
@Override
public int getScreenWidth()
{
return MC.getWindow().getWidth();
}
@Override
public int getScreenHeight()
{
return MC.getWindow().getHeight();
}
private RenderTarget getRenderTarget() {
RenderTarget r = null; //MC.levelRenderer.getCloudsTarget();
return r!=null ? r : MC.getMainRenderTarget();
}
@Override
public int getTargetFrameBuffer() {
return getRenderTarget().frameBufferId;
}
@Override
public int getTargetFrameBufferViewportWidth() {
return getRenderTarget().viewWidth;
}
@Override
public int getTargetFrameBufferViewportHeight() {
return getRenderTarget().viewHeight;
}
/**
* This method returns the ChunkPos of all chunks that Minecraft
* is going to render this frame. <br><br>
* <p>
*/
public boolean usingBackupGetVanillaRenderedChunks = false;
@Override
public HashSet<AbstractChunkPosWrapper> getVanillaRenderedChunks() {
ISodiumAccessor sodium = ModAccessorHandler.get(ISodiumAccessor.class);
if (sodium != null) {
return sodium.getNormalRenderedChunks();
}
IOptifineAccessor optifine = ModAccessorHandler.get(IOptifineAccessor.class);
if (optifine != null) {
HashSet<AbstractChunkPosWrapper> pos = optifine.getNormalRenderedChunks();
if (pos == null)
pos = getMaximumRenderedChunks();
return pos;
}
if (!usingBackupGetVanillaRenderedChunks) {
try {
LevelRenderer levelRenderer = MC.levelRenderer;
Collection<LevelRenderer.RenderChunkInfo> chunks =
#if PRE_MC_1_18_1 levelRenderer.renderChunks;
#else levelRenderer.renderChunkStorage.get().renderChunks; #endif
return (chunks.stream().map((chunk) -> {
AABB chunkBoundingBox =
#if PRE_MC_1_18_2 chunk.chunk.bb;
#else chunk.chunk.getBoundingBox(); #endif
return FACTORY.createChunkPos(Math.floorDiv((int) chunkBoundingBox.minX, 16),
Math.floorDiv((int) chunkBoundingBox.minZ, 16));
}).collect(Collectors.toCollection(HashSet::new)));
} catch (LinkageError e) {
try {
MinecraftClientWrapper.INSTANCE.sendChatMessage(
"\u00A7e\u00A7l\u00A7uWARNING: Distant Horizons: getVanillaRenderedChunks method failed."
+ " Using Backup Method.");
MinecraftClientWrapper.INSTANCE.sendChatMessage(
"\u00A7eOverdraw prevention will be worse than normal.");
} catch (Exception e2) {
}
ApiShared.LOGGER.error("getVanillaRenderedChunks Error: ", e);
usingBackupGetVanillaRenderedChunks = true;
}
}
return getMaximumRenderedChunks();
}
@Override
public ILightMapWrapper getLightmapWrapper() {
return lightmap;
}
@Override
public boolean isFogStateSpecial() {
#if PRE_MC_1_17_1
Camera camera = GAME_RENDERER.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 = GAME_RENDERER.getMainCamera().getEntity();
boolean isBlind = (entity instanceof LivingEntity) && ((LivingEntity)entity).hasEffect(MobEffects.BLINDNESS);
return GAME_RENDERER.getMainCamera().getFluidInCamera() != FogType.NONE || isBlind;
#endif
}
@Override
public boolean tryDisableVanillaFog() {
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,60 +0,0 @@
/*
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
* licensed under the GNU GPL 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 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.minecraft;
import com.seibel.lod.core.wrapperInterfaces.minecraft.IProfilerWrapper;
import net.minecraft.util.profiling.ProfilerFiller;
/**
* @author James Seibel
* @version 11-20-2021
*/
public class ProfilerWrapper implements IProfilerWrapper
{
public ProfilerFiller profiler;
public ProfilerWrapper(ProfilerFiller newProfiler)
{
profiler = newProfiler;
}
/** starts a new section inside the currently running section */
@Override
public void push(String newSection)
{
profiler.push(newSection);
}
/** ends the currently running section and starts a new one */
@Override
public void popPush(String newSection)
{
profiler.popPush(newSection);
}
/** ends the currently running section */
@Override
public void pop()
{
profiler.pop();
}
}
@@ -1,71 +0,0 @@
/*
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
* licensed under the GNU GPL 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 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.misc;
import com.mojang.blaze3d.platform.NativeImage;
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
* @version 11-21-2021
*/
public class LightMapWrapper implements ILightMapWrapper
{
private int textureId = 0;
public LightMapWrapper()
{
}
private void createLightmap(NativeImage image)
{
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
public void bind() {
GL32.glBindTexture(GL32.GL_TEXTURE_2D, textureId);
}
@Override
public void unbind() {
GL32.glBindTexture(GL32.GL_TEXTURE_2D, 0);
}
}
@@ -1,308 +0,0 @@
/*
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
* licensed under the GNU GPL 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 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.List;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.function.Function;
import java.util.function.Supplier;
import com.google.common.collect.ImmutableBiMap;
import com.google.common.collect.ImmutableList;
import com.seibel.lod.core.util.LodUtil;
import com.seibel.lod.core.wrapperInterfaces.world.IBiomeWrapper;
import net.minecraft.data.BuiltinRegistries;
#if POST_MC_1_19
import net.minecraft.data.worldgen.biome.EndBiomes;
import net.minecraft.data.worldgen.biome.NetherBiomes;
#endif
import net.minecraft.resources.ResourceKey;
import net.minecraft.world.level.biome.Biome;
import net.minecraft.world.level.biome.Biomes;
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. */
#if PRE_MC_1_19
@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:
colorInt = biome.getGrassColor(x,z);
//FIXME: Repair what James did - LeeTom
// Color tmp = LodUtil.intToColor(biome.getGrassColor(x, z));
// tmp = tmp.darker();
// colorInt = LodUtil.colorToInt(tmp);
break;
}
return colorInt;
}
#else
private static int _colorEnd(Biome b) {
return Blocks.END_STONE.defaultMaterialColor().col;
}
private static int _colorNether(Biome b) {
return Blocks.NETHERRACK.defaultMaterialColor().col;
}
private static int _colorSand(Biome b) {
return Blocks.SAND.defaultMaterialColor().col;
}
private static int _colorStone(Biome b) {
return Blocks.STONE.defaultMaterialColor().col;
}
private static int _colorGravel(Biome b) {
return Blocks.GRAVEL.defaultMaterialColor().col;
}
private static int _colorDripStone(Biome b) {
return Blocks.DRIPSTONE_BLOCK.defaultMaterialColor().col;
}
private static int _colorMoss(Biome b) {
return Blocks.MOSS_BLOCK.defaultMaterialColor().col;
}
private static int _colorSculk(Biome b) {
return Blocks.SCULK.defaultMaterialColor().col;
}
private static int _colorMushoom(Biome b) {
return Blocks.MYCELIUM.defaultMaterialColor().col;
}
private static int _colorBamboo(Biome b) {
return Blocks.BAMBOO.defaultMaterialColor().col;
}
private static int _colorSnow(Biome b) {
return Blocks.SNOW.defaultMaterialColor().col;
}
private static int _colorIce(Biome b) {
return Blocks.ICE.defaultMaterialColor().col;
}
private static int _colorRedSand(Biome b) {
return Blocks.RED_SAND.defaultMaterialColor().col;
}
private static int _colorSoulSand(Biome b) {
return Blocks.SOUL_SAND.defaultMaterialColor().col;
}
private static int _colorBasalt(Biome b) {
return Blocks.BASALT.defaultMaterialColor().col;
}
private static int _colorWater(Biome b) {
return b.getWaterColor();
}
private static int _colorFoliage(Biome b) {
return b.getFoliageColor();
}
private static Biome _get(ResourceKey<Biome> r) {
return BuiltinRegistries.BIOME.getOrThrow(r);
}
//FIXME: THIS IS HELL!
private static final ImmutableBiMap<Biome, Function<Biome, Integer>> BIOME_COLOR_MAP =
ImmutableBiMap.<Biome, Function<Biome, Integer>>builder()
.put(_get(Biomes.SNOWY_PLAINS), BiomeWrapper::_colorSnow)
.put(_get(Biomes.ICE_SPIKES), BiomeWrapper::_colorIce)
.put(_get(Biomes.DESERT), BiomeWrapper::_colorSand)
.put(_get(Biomes.SWAMP), BiomeWrapper::_colorWater)
.put(_get(Biomes.MANGROVE_SWAMP), BiomeWrapper::_colorWater)
.put(_get(Biomes.FOREST), BiomeWrapper::_colorFoliage)
.put(_get(Biomes.FLOWER_FOREST), BiomeWrapper::_colorFoliage)
.put(_get(Biomes.BIRCH_FOREST), BiomeWrapper::_colorFoliage)
.put(_get(Biomes.DARK_FOREST), BiomeWrapper::_colorFoliage)
.put(_get(Biomes.OLD_GROWTH_BIRCH_FOREST), BiomeWrapper::_colorFoliage)
.put(_get(Biomes.OLD_GROWTH_PINE_TAIGA), BiomeWrapper::_colorFoliage)
.put(_get(Biomes.OLD_GROWTH_SPRUCE_TAIGA), BiomeWrapper::_colorFoliage)
.put(_get(Biomes.TAIGA), BiomeWrapper::_colorFoliage)
.put(_get(Biomes.SNOWY_TAIGA), BiomeWrapper::_colorSnow)
.put(_get(Biomes.WINDSWEPT_GRAVELLY_HILLS), BiomeWrapper::_colorGravel)
.put(_get(Biomes.WINDSWEPT_FOREST), BiomeWrapper::_colorFoliage)
.put(_get(Biomes.JUNGLE), BiomeWrapper::_colorFoliage)
.put(_get(Biomes.BAMBOO_JUNGLE), BiomeWrapper::_colorBamboo)
.put(_get(Biomes.BADLANDS), BiomeWrapper::_colorRedSand)
.put(_get(Biomes.ERODED_BADLANDS), BiomeWrapper::_colorRedSand)
.put(_get(Biomes.WOODED_BADLANDS), BiomeWrapper::_colorStone)
.put(_get(Biomes.GROVE), BiomeWrapper::_colorSnow)
.put(_get(Biomes.SNOWY_SLOPES), BiomeWrapper::_colorSnow)
.put(_get(Biomes.FROZEN_PEAKS), BiomeWrapper::_colorIce)
.put(_get(Biomes.JAGGED_PEAKS), BiomeWrapper::_colorSnow)
.put(_get(Biomes.STONY_PEAKS), BiomeWrapper::_colorStone)
.put(_get(Biomes.RIVER), BiomeWrapper::_colorWater)
.put(_get(Biomes.FROZEN_RIVER), BiomeWrapper::_colorIce)
.put(_get(Biomes.BEACH), BiomeWrapper::_colorSand)
.put(_get(Biomes.SNOWY_BEACH), BiomeWrapper::_colorSnow)
.put(_get(Biomes.STONY_SHORE), BiomeWrapper::_colorStone)
.put(_get(Biomes.WARM_OCEAN), BiomeWrapper::_colorWater)
.put(_get(Biomes.LUKEWARM_OCEAN), BiomeWrapper::_colorWater)
.put(_get(Biomes.DEEP_LUKEWARM_OCEAN), BiomeWrapper::_colorWater)
.put(_get(Biomes.OCEAN), BiomeWrapper::_colorWater)
.put(_get(Biomes.DEEP_OCEAN), BiomeWrapper::_colorWater)
.put(_get(Biomes.COLD_OCEAN), BiomeWrapper::_colorWater)
.put(_get(Biomes.DEEP_COLD_OCEAN), BiomeWrapper::_colorWater)
.put(_get(Biomes.FROZEN_OCEAN), BiomeWrapper::_colorIce)
.put(_get(Biomes.DEEP_FROZEN_OCEAN), BiomeWrapper::_colorIce)
.put(_get(Biomes.MUSHROOM_FIELDS), BiomeWrapper::_colorMushoom)
.put(_get(Biomes.DRIPSTONE_CAVES), BiomeWrapper::_colorDripStone)
.put(_get(Biomes.LUSH_CAVES), BiomeWrapper::_colorMoss)
.put(_get(Biomes.DEEP_DARK), BiomeWrapper::_colorSculk)
.put(_get(Biomes.NETHER_WASTES), BiomeWrapper::_colorNether)
.put(_get(Biomes.WARPED_FOREST), BiomeWrapper::_colorNether)
.put(_get(Biomes.CRIMSON_FOREST), BiomeWrapper::_colorNether)
.put(_get(Biomes.SOUL_SAND_VALLEY), BiomeWrapper::_colorSoulSand)
.put(_get(Biomes.BASALT_DELTAS), BiomeWrapper::_colorBasalt)
.put(_get(Biomes.THE_END), BiomeWrapper::_colorEnd)
.put(_get(Biomes.END_HIGHLANDS), BiomeWrapper::_colorEnd)
.put(_get(Biomes.END_MIDLANDS), BiomeWrapper::_colorEnd)
.put(_get(Biomes.SMALL_END_ISLANDS), BiomeWrapper::_colorEnd)
.put(_get(Biomes.END_BARRENS), BiomeWrapper::_colorEnd)
.build();
@Override
public int getColorForBiome(int x, int z)
{
int colorInt;
Function<Biome, Integer> colorFunction = BIOME_COLOR_MAP.get(biome);
if (colorFunction != null)
{
colorInt = colorFunction.apply(biome);
}
else
{
colorInt = biome.getGrassColor(x, z);
}
return colorInt;
}
#endif
@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);
}
}
@@ -1,82 +0,0 @@
/*
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
* licensed under the GNU GPL 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 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.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import com.seibel.lod.core.wrapperInterfaces.world.IDimensionTypeWrapper;
import net.minecraft.world.level.dimension.DimensionType;
/**
*
* @author James Seibel
* @version 11-21-2021
*/
public class DimensionTypeWrapper implements IDimensionTypeWrapper
{
private static final ConcurrentMap<DimensionType, DimensionTypeWrapper> dimensionTypeWrapperMap = new ConcurrentHashMap<>();
private final DimensionType dimensionType;
public DimensionTypeWrapper(DimensionType dimensionType)
{
this.dimensionType = dimensionType;
}
public static DimensionTypeWrapper getDimensionTypeWrapper(DimensionType dimensionType)
{
//first we check if the biome has already been wrapped
if(dimensionTypeWrapperMap.containsKey(dimensionType) && dimensionTypeWrapperMap.get(dimensionType) != null)
return dimensionTypeWrapperMap.get(dimensionType);
//if it hasn't been created yet, we create it and save it in the map
DimensionTypeWrapper dimensionTypeWrapper = new DimensionTypeWrapper(dimensionType);
dimensionTypeWrapperMap.put(dimensionType, dimensionTypeWrapper);
//we return the newly created wrapper
return dimensionTypeWrapper;
}
public static void clearMap()
{
dimensionTypeWrapperMap.clear();
}
@Override
public String getDimensionName()
{
return dimensionType.effectsLocation().getPath();
}
@Override
public boolean hasCeiling()
{
return dimensionType.hasCeiling();
}
@Override
public boolean hasSkyLight()
{
return dimensionType.hasSkyLight();
}
}
@@ -1,189 +0,0 @@
/*
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
* licensed under the GNU GPL 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 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()
{
#if PRE_MC_1_17_1
return (short) 0;
#else
return (short) world.getMinBuildHeight();
#endif
}
/** @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);
}
}
@@ -1,633 +0,0 @@
/*
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
* licensed under the GNU GPL v3 License.
*
* Copyright (C) 2021 Tom Lee (TomTheFurry)
* 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 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.worldGeneration;
import com.seibel.lod.core.logging.ConfigBasedLogger;
import com.seibel.lod.core.logging.ConfigBasedSpamLogger;
import com.seibel.lod.core.builders.lodBuilding.LodBuilder;
import com.seibel.lod.core.builders.lodBuilding.LodBuilderConfig;
import com.seibel.lod.core.enums.config.DistanceGenerationMode;
import com.seibel.lod.core.enums.config.LightGenerationMode;
import com.seibel.lod.core.handlers.dependencyInjection.SingletonHandler;
import com.seibel.lod.core.objects.lod.LodDimension;
import com.seibel.lod.core.util.gridList.ArrayGridList;
import com.seibel.lod.core.util.LodThreadFactory;
import com.seibel.lod.core.wrapperInterfaces.config.ILodConfigWrapperSingleton;
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 java.time.Duration;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import com.seibel.lod.common.wrappers.DependencySetupDoneCheck;
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.LightGetterAdaptor;
import com.seibel.lod.common.wrappers.worldGeneration.mimicObject.LightedWorldGenRegion;
import com.seibel.lod.common.wrappers.worldGeneration.mimicObject.WorldGenLevelLightEngine;
import com.seibel.lod.common.wrappers.worldGeneration.step.StepBiomes;
import com.seibel.lod.common.wrappers.worldGeneration.step.StepFeatures;
import com.seibel.lod.common.wrappers.worldGeneration.step.StepLight;
import com.seibel.lod.common.wrappers.worldGeneration.step.StepNoise;
import com.seibel.lod.common.wrappers.worldGeneration.step.StepStructureReference;
import com.seibel.lod.common.wrappers.worldGeneration.step.StepStructureStart;
import com.seibel.lod.common.wrappers.worldGeneration.step.StepSurface;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.level.ChunkPos;
import net.minecraft.world.level.chunk.ChunkAccess;
import net.minecraft.world.level.chunk.ChunkGenerator;
import net.minecraft.world.level.chunk.ChunkStatus;
import net.minecraft.world.level.chunk.LevelChunk;
import net.minecraft.world.level.chunk.ProtoChunk;
import net.minecraft.world.level.chunk.UpgradeData;
import net.minecraft.world.level.levelgen.DebugLevelSource;
import net.minecraft.world.level.levelgen.FlatLevelSource;
import net.minecraft.world.level.levelgen.NoiseBasedChunkGenerator;
import net.minecraft.core.Registry;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.level.lighting.LevelLightEngine;
import org.apache.logging.log4j.LogManager;
/*
Total: 3.135214124s
=====================================
Empty Chunks: 0.000558328s
StructureStart Step: 0.025177207s
StructureReference Step: 0.00189559s
Biome Step: 0.13789155s
Noise Step: 1.570347555s
Surface Step: 0.741238194s
Carver Step: 0.000009923s
Feature Step: 0.389072425s
Lod Generation: 0.269023348s
*/
public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnvionmentWrapper
{
private static final ILodConfigWrapperSingleton CONFIG = SingletonHandler.get(ILodConfigWrapperSingleton.class);
public static final ConfigBasedSpamLogger PREF_LOGGER =
new ConfigBasedSpamLogger(LogManager.getLogger("LodWorldGen"),
() -> CONFIG.client().advanced().debugging().debugSwitch().getLogWorldGenPerformance(),1);
public static final ConfigBasedLogger EVENT_LOGGER =
new ConfigBasedLogger(LogManager.getLogger("LodWorldGen"),
() -> CONFIG.client().advanced().debugging().debugSwitch().getLogWorldGenEvent());
public static final ConfigBasedLogger LOAD_LOGGER =
new ConfigBasedLogger(LogManager.getLogger("LodWorldGen"),
() -> CONFIG.client().advanced().debugging().debugSwitch().getLogWorldGenLoadEvent());
//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 final int SIZE = 50;
Rolling totalTime = new Rolling(SIZE);
Rolling emptyTime = new Rolling(SIZE);
Rolling structStartTime = new Rolling(SIZE);
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;
totalTime.add(e.endNano - preTime);
if (e.emptyNano != 0)
{
emptyTime.add(e.emptyNano - preTime);
preTime = e.emptyNano;
}
if (e.structStartNano != 0)
{
structStartTime.add(e.structStartNano - preTime);
preTime = e.structStartNano;
}
if (e.structRefNano != 0)
{
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);
}
}
public String toString()
{
return "Total: " + Duration.ofNanos((long) totalTime.getAverage()) + ", Empty/LoadChunk: "
+ Duration.ofNanos((long) emptyTime.getAverage()) + ", StructStart: "
+ Duration.ofNanos((long) structStartTime.getAverage()) + ", StructRef: "
+ Duration.ofNanos((long) structRefTime.getAverage()) + ", Biome: "
+ Duration.ofNanos((long) biomeTime.getAverage()) + ", Noise: "
+ Duration.ofNanos((long) noiseTime.getAverage()) + ", Surface: "
+ Duration.ofNanos((long) surfaceTime.getAverage()) + ", Carver: "
+ Duration.ofNanos((long) carverTime.getAverage()) + ", Feature: "
+ Duration.ofNanos((long) featureTime.getAverage()) + ", Light: "
+ Duration.ofNanos((long) lightTime.getAverage()) + ", Lod: "
+ Duration.ofNanos((long) lodTime.getAverage());
}
}
public static final int TIMEOUT_SECONDS = 60;
//=================Generation Step===================
public final LinkedList<GenerationEvent> events = new LinkedList<>();
public final GlobalParameters params;
public final StepStructureStart stepStructureStart = new StepStructureStart(this);
public final StepStructureReference stepStructureReference = new StepStructureReference(this);
public final StepBiomes stepBiomes = new StepBiomes(this);
public final StepNoise stepNoise = new StepNoise(this);
public final StepSurface stepSurface = new StepSurface(this);
public final StepFeatures stepFeatures = new StepFeatures(this);
public final StepLight stepLight = new StepLight(this);
public boolean unsafeThreadingRecorded = false;
//public boolean safeMode = false;
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 int EXCEPTION_COUNTER_TRIGGER = 20;
public static final int RANGE_TO_RANGE_EMPTY_EXTENSION = 1;
public int unknownExceptionCount = 0;
public long lastExceptionTriggerTime = 0;
public static final LodThreadFactory threadFactory = new LodThreadFactory("Gen-Worker-Thread", Thread.MIN_PRIORITY);
public static ThreadLocal<Boolean> isDistantGeneratorThread = new ThreadLocal<>();
public static boolean isCurrentThreadDistantGeneratorThread() {
return (isDistantGeneratorThread.get() != null);
}
static {
DependencySetupDoneCheck.getIsCurrentThreadDistantGeneratorThread = BatchGenerationEnvironment::isCurrentThreadDistantGeneratorThread;
}
public ExecutorService executors = Executors.newFixedThreadPool(
CONFIG.client().advanced().threading()._getWorldGenerationThreadPoolSize(), threadFactory);
public <T> T joinSync(CompletableFuture<T> f) {
if (!unsafeThreadingRecorded && !f.isDone()) {
EVENT_LOGGER.error("Unsafe Threading in Chunk Generator: ", new RuntimeException("Concurrent future"));
EVENT_LOGGER.error("To increase stability, it is recommended to set world generation threads count to 1.");
unsafeThreadingRecorded = true;
}
return f.join();
}
public void resizeThreadPool(int newThreadCount)
{
executors = Executors.newFixedThreadPool(newThreadCount,
new LodThreadFactory("Gen-Worker-Thread", Thread.MIN_PRIORITY));
}
public boolean tryAddPoint(int px, int pz, int range, Steps target, boolean genAllDetails, double runTimeRatio)
{
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, runTimeRatio));
return true;
}
public void updateAllFutures()
{
if (unknownExceptionCount > 0) {
if (System.nanoTime() - lastExceptionTriggerTime >= EXCEPTION_TIMER_RESET_TIME) {
unknownExceptionCount = 0;
}
}
// Update all current out standing jobs
Iterator<GenerationEvent> iter = events.iterator();
while (iter.hasNext())
{
GenerationEvent event = iter.next();
if (event.isCompleted())
{
try
{
event.join();
}
catch (Throwable e)
{
EVENT_LOGGER.error("Batching World Generator: Event {} gotten an exception", event);
EVENT_LOGGER.error("Exception: ", e);
unknownExceptionCount++;
lastExceptionTriggerTime = System.nanoTime();
}
finally
{
iter.remove();
}
}
else if (event.hasTimeout(TIMEOUT_SECONDS, TimeUnit.SECONDS))
{
EVENT_LOGGER.error("Batching World Generator: " + event + " timed out and terminated!");
EVENT_LOGGER.info("Dump PrefEvent: " + event.pEvent);
try
{
if (!event.terminate())
EVENT_LOGGER.error("Failed to terminate the stuck generation event!");
}
finally
{
iter.remove();
}
}
}
if (unknownExceptionCount > EXCEPTION_COUNTER_TRIGGER) {
EVENT_LOGGER.error("Too many exceptions in Batching World Generator! Disabling the generator.");
unknownExceptionCount = 0;
CONFIG.client().worldGenerator().setEnableDistantGeneration(false);
}
}
public BatchGenerationEnvironment(IWorldWrapper serverlevel, LodBuilder lodBuilder, LodDimension lodDim)
{
super(serverlevel, lodBuilder, lodDim);
EVENT_LOGGER.info("================WORLD_GEN_STEP_INITING=============");
ChunkGenerator generator = ((WorldWrapper) serverlevel).getServerWorld().getChunkSource().getGenerator();
if (!(generator instanceof NoiseBasedChunkGenerator ||
generator instanceof DebugLevelSource ||
generator instanceof FlatLevelSource)) {
if (generator.getClass().toString().equals("class com.terraforged.mod.chunk.TFChunkGenerator")) {
EVENT_LOGGER.info("TerraForge Chunk Generator detected: [{}], Distant Generation will try its best to support it.", 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);
}
@SuppressWarnings("resource")
public static ChunkAccess loadOrMakeChunk(ChunkPos chunkPos, ServerLevel level, LevelLightEngine lightEngine)
{
CompoundTag chunkData = null;
try
{
#if POST_MC_1_19
chunkData = level.getChunkSource().chunkMap.readChunk(chunkPos).get().orElse(null);
#else
chunkData = level.getChunkSource().chunkMap.readChunk(chunkPos);
#endif
}
catch (Exception e)
{
LOAD_LOGGER.error("DistantHorizons: Couldn't load chunk {}", chunkPos, e);
}
if (chunkData == 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
{
try {
return ChunkLoader.read(level, lightEngine, chunkPos, chunkData);
} catch (Exception e) {
LOAD_LOGGER.error("DistantHorizons: Couldn't load chunk {}", chunkPos, e);
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
);
}
}
}
public void generateLodFromList(GenerationEvent e)
{
EVENT_LOGGER.debug("Lod Generate Event: " + e.pos);
e.pEvent.beginNano = System.nanoTime();
ArrayGridList<ChunkAccess> referencedChunks;
ArrayGridList<ChunkAccess> genChunks;
DistanceGenerationMode generationMode;
LightedWorldGenRegion region;
WorldGenLevelLightEngine lightEngine;
LightGetterAdaptor adaptor;
int refRange = e.range + RANGE_TO_RANGE_EMPTY_EXTENSION;
int refOffsetX = e.pos.x - refRange;
int refOffsetZ = e.pos.z - refRange;
try
{
adaptor = new LightGetterAdaptor(params.level);
lightEngine = new WorldGenLevelLightEngine(adaptor);
@SuppressWarnings("resource")
EmptyChunkGenerator generator = (int x, int z) ->
{
ChunkPos chunkPos = new ChunkPos(x, z);
ChunkAccess target = null;
try
{
target = loadOrMakeChunk(chunkPos, params.level, lightEngine);
}
catch (RuntimeException e2)
{
// Continue...
}
if (target == null)
target = new ProtoChunk(chunkPos, UpgradeData.EMPTY
#if POST_MC_1_17_1, params.level #endif
#if POST_MC_1_18_1, params.biomes, null #endif
);
return target;
};
referencedChunks = new ArrayGridList<>(refRange*2+1,
(x,z) -> generator.generate(x + refOffsetX,z + refOffsetZ)
);
e.pEvent.emptyNano = System.nanoTime();
e.refreshTimeout();
region = new LightedWorldGenRegion(params.level, lightEngine, referencedChunks,
ChunkStatus.STRUCTURE_STARTS, refRange, e.lightMode, generator);
adaptor.setRegion(region);
e.tParam.makeStructFeat(region, params);
genChunks = new ArrayGridList<>(referencedChunks, RANGE_TO_RANGE_EMPTY_EXTENSION,
referencedChunks.gridSize - RANGE_TO_RANGE_EMPTY_EXTENSION);
generateDirect(e, genChunks, e.target, region);
}
catch (StepStructureStart.StructStartCorruptedException f)
{
e.tParam.markAsInvalid();
return;
}
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 ox = 0; ox < genChunks.gridSize; ox++)
{
ChunkAccess target = genChunks.get(ox, oy);
ChunkWrapper wrappedChunk = new ChunkWrapper(target, region);
if (!wrappedChunk.isLightCorrect()) {
throw new RuntimeException("The generated chunk somehow has isLightCorrect() returning false");
}
boolean isFull = target.getStatus() == ChunkStatus.FULL || target instanceof LevelChunk;
#if POST_MC_1_18_1
boolean isPartial = target.isOldNoiseGeneration();
#endif
if (isFull)
{
LOAD_LOGGER.info("Detected full existing chunk at {}", target.getPos());
params.lodBuilder.generateLodNodeFromChunk(params.lodDim, wrappedChunk,
new LodBuilderConfig(DistanceGenerationMode.FULL), true, e.genAllDetails);
}
#if POST_MC_1_18_1
else if (isPartial)
{
LOAD_LOGGER.info("Detected old existing chunk at {}", target.getPos());
params.lodBuilder.generateLodNodeFromChunk(params.lodDim, wrappedChunk,
new LodBuilderConfig(generationMode), true, e.genAllDetails);
}
#endif
else if (target.getStatus() == ChunkStatus.EMPTY && generationMode == DistanceGenerationMode.NONE)
{
params.lodBuilder.generateLodNodeFromChunk(params.lodDim,wrappedChunk,
LodBuilderConfig.getFillVoidConfig(), true, e.genAllDetails);
}
else
{
params.lodBuilder.generateLodNodeFromChunk(params.lodDim, wrappedChunk,
new LodBuilderConfig(generationMode), true, e.genAllDetails);
}
if (e.lightMode == LightGenerationMode.FANCY || isFull)
{
lightEngine.retainData(target.getPos(), false);
}
}
}
e.pEvent.endNano = System.nanoTime();
e.refreshTimeout();
if (PREF_LOGGER.canMaybeLog())
{
e.tParam.perf.recordEvent(e.pEvent);
PREF_LOGGER.infoInc("{}", e.tParam.perf);
}
}
public void generateDirect(GenerationEvent e, ArrayGridList<ChunkAccess> subRange, Steps step,
LightedWorldGenRegion region)
{
try
{
subRange.forEach((chunk) ->
{
if (chunk instanceof ProtoChunk)
{
((ProtoChunk) chunk).setLightEngine(region.getLightEngine());
region.getLightEngine().retainData(chunk.getPos(), true);
}
});
if (step == Steps.Empty)
return;
stepStructureStart.generateGroup(e.tParam, region, subRange);
e.pEvent.structStartNano = System.nanoTime();
e.refreshTimeout();
if (step == Steps.StructureStart)
return;
stepStructureReference.generateGroup(e.tParam, region, subRange);
e.pEvent.structRefNano = System.nanoTime();
e.refreshTimeout();
if (step == Steps.StructureReference)
return;
stepBiomes.generateGroup(e.tParam, region, subRange);
e.pEvent.biomeNano = System.nanoTime();
e.refreshTimeout();
if (step == Steps.Biomes)
return;
stepNoise.generateGroup(e.tParam, region, subRange);
e.pEvent.noiseNano = System.nanoTime();
e.refreshTimeout();
if (step == Steps.Noise)
return;
stepSurface.generateGroup(e.tParam, region, subRange);
e.pEvent.surfaceNano = System.nanoTime();
e.refreshTimeout();
if (step == Steps.Surface)
return;
if (step == Steps.Carvers)
return;
stepFeatures.generateGroup(e.tParam, region, subRange);
e.pEvent.featureNano = System.nanoTime();
e.refreshTimeout();
}
finally
{
switch (region.lightMode)
{
case FANCY:
stepLight.generateGroup(region.getLightEngine(), subRange);
break;
case FAST:
subRange.forEach((p) ->
{
if (p instanceof ProtoChunk)
((ProtoChunk) p).setLightCorrect(true);
#if POST_MC_1_18_1
if (p instanceof LevelChunk) {
((LevelChunk) p).setLightCorrect(true);
((LevelChunk) p).setClientLightReady(true);
}
#endif
});
break;
}
e.pEvent.lightNano = System.nanoTime();
e.refreshTimeout();
}
}
public interface EmptyChunkGenerator
{
ChunkAccess generate(int x, int z);
}
@Override
public int getEventCount() {
return events.size();
}
@Override
public void stop(boolean blocking) {
EVENT_LOGGER.info("Batch Chunk Generator shutting down...");
executors.shutdownNow();
if (blocking) try {
if (!executors.awaitTermination(10, TimeUnit.SECONDS)) {
EVENT_LOGGER.error("Batch Chunk Generator shutdown failed! Ignoring child threads...");
}
} catch (InterruptedException e) {
EVENT_LOGGER.error("Batch Chunk Generator shutdown failed! Ignoring child threads...", e);
}
}
}
@@ -1,142 +0,0 @@
/*
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
* licensed under the GNU GPL 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 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.worldGeneration;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import com.seibel.lod.common.wrappers.worldGeneration.BatchGenerationEnvironment.PrefEvent;
import com.seibel.lod.core.api.ApiShared;
import com.seibel.lod.core.enums.config.LightGenerationMode;
import com.seibel.lod.core.handlers.dependencyInjection.SingletonHandler;
import com.seibel.lod.core.util.LodUtil;
import com.seibel.lod.core.wrapperInterfaces.config.ILodConfigWrapperSingleton;
import com.seibel.lod.core.wrapperInterfaces.worldGeneration.AbstractBatchGenerationEnvionmentWrapper.Steps;
import net.minecraft.world.level.ChunkPos;
//======================= Main Event class======================
public final class GenerationEvent
{
static private final ILodConfigWrapperSingleton CONFIG = SingletonHandler.get(ILodConfigWrapperSingleton.class);
private static int generationFutureDebugIDs = 0;
final ThreadedParameters tParam;
final ChunkPos pos;
final int range;
final Future<?> future;
long creationNanotime;
final int id;
final Steps target;
final LightGenerationMode lightMode;
final PrefEvent pEvent = new PrefEvent();
final boolean genAllDetails;
final double runTimeRatio;
public GenerationEvent(ChunkPos pos, int range, BatchGenerationEnvironment generationGroup,
Steps target, boolean genAllDetails, double runTimeRatio)
{
creationNanotime = System.nanoTime();
this.pos = pos;
this.range = range;
id = generationFutureDebugIDs++;
this.target = target;
this.tParam = ThreadedParameters.getOrMake(generationGroup.params);
LightGenerationMode mode = CONFIG.client().worldGenerator().getLightGenerationMode();
this.lightMode = mode;
this.genAllDetails = genAllDetails;
this.runTimeRatio = runTimeRatio;
future = generationGroup.executors.submit(() ->
{
long startTime = System.nanoTime();
BatchGenerationEnvironment.isDistantGeneratorThread.set(true);
try {
generationGroup.generateLodFromList(this);
} finally {
BatchGenerationEnvironment.isDistantGeneratorThread.remove();
if (!Thread.interrupted() && runTimeRatio < 1.0) {
long endTime = System.nanoTime();
try {
long deltaMs = TimeUnit.NANOSECONDS.toMillis(endTime - startTime);
Thread.sleep((long) (deltaMs/runTimeRatio - deltaMs));
} catch (InterruptedException ignored) {
}
}
}
});
}
public boolean isCompleted()
{
return future.isDone();
}
public boolean hasTimeout(int duration, TimeUnit unit)
{
long currentTime = System.nanoTime();
long delta = currentTime - creationNanotime;
return (delta > TimeUnit.NANOSECONDS.convert(duration, unit));
}
public boolean terminate()
{
ApiShared.LOGGER.info("======================DUMPING ALL THREADS FOR WORLD GEN=======================");
BatchGenerationEnvironment.threadFactory.dumpAllThreadStacks();
future.cancel(true);
return future.isCancelled();
}
public void join()
{
try
{
future.get();
}
catch (InterruptedException | ExecutionException e)
{
throw new RuntimeException(e.getCause()==null? e : e.getCause());
}
}
public boolean tooClose(int cx, int cz, int cr)
{
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()
{
creationNanotime = System.nanoTime();
LodUtil.checkInterruptsUnchecked();
}
@Override
public String toString()
{
return id + ":" + range + "@" + pos + "(" + target + ")";
}
}
@@ -1,92 +0,0 @@
/*
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
* licensed under the GNU GPL 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 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.worldGeneration;
import com.mojang.datafixers.DataFixer;
import com.seibel.lod.core.builders.lodBuilding.LodBuilder;
import com.seibel.lod.core.objects.lod.LodDimension;
import net.minecraft.core.Registry;
import net.minecraft.core.RegistryAccess;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ThreadedLevelLightEngine;
import net.minecraft.world.level.biome.Biome;
import net.minecraft.world.level.biome.BiomeManager;
import net.minecraft.world.level.chunk.ChunkGenerator;
#if POST_MC_1_18_1
import net.minecraft.world.level.chunk.storage.ChunkScanAccess;
#endif
import net.minecraft.world.level.levelgen.WorldGenSettings;
#if PRE_MC_1_19
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;
public final class GlobalParameters
{
public final ChunkGenerator generator;
#if PRE_MC_1_19
public final StructureManager structures;
#else
public final StructureTemplateManager structures;
public final RandomState randomState;
#endif
public final WorldGenSettings worldGenSettings;
public final ThreadedLevelLightEngine lightEngine;
public final LodBuilder lodBuilder;
public final LodDimension lodDim;
public final Registry<Biome> biomes;
public final RegistryAccess registry;
public final long worldSeed;
public final ServerLevel level; // TODO: Figure out a way to remove this. Maybe ClientLevel also works?
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)
{
this.lodBuilder = lodBuilder;
this.lodDim = lodDim;
this.level = level;
lightEngine = (ThreadedLevelLightEngine) level.getLightEngine();
MinecraftServer server = level.getServer();
WorldData worldData = server.getWorldData();
worldGenSettings = worldData.worldGenSettings();
registry = server.registryAccess();
biomes = registry.registryOrThrow(Registry.BIOME_REGISTRY);
worldSeed = worldGenSettings.seed();
#if POST_MC_1_18_1
biomeManager = new BiomeManager(level, BiomeManager.obfuscateSeed(worldSeed));
chunkScanner = level.getChunkSource().chunkScanner();
#endif
structures = server.getStructureManager();
generator = level.getChunkSource().getGenerator();
fixerUpper = server.getFixerUpper();
#if POST_MC_1_19
randomState = level.getChunkSource().randomState();
#endif
}
}
@@ -1,53 +0,0 @@
/*
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
* licensed under the GNU GPL 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 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.worldGeneration;
//FIXME: Move this outside the WorldGenerationStep thingy
public class Rolling
{
private final int size;
private double total = 0d;
private int index = 0;
private final double[] samples;
public Rolling(int size)
{
this.size = size;
samples = new double[size];
for (int i = 0; i < size; i++)
samples[i] = 0d;
}
public void add(double x)
{
total -= samples[index];
samples[index] = x;
total += x;
if (++index == size)
index = 0; // cheaper than modulus
}
public double getAverage()
{
return total / size;
}
}
@@ -1,78 +0,0 @@
/*
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
* licensed under the GNU GPL 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 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.worldGeneration;
import com.seibel.lod.common.wrappers.worldGeneration.BatchGenerationEnvironment.PerfCalculator;
import com.seibel.lod.common.wrappers.worldGeneration.mimicObject.WorldGenStructFeatManager;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.level.WorldGenLevel;
#if POST_MC_1_18_1
import net.minecraft.world.level.levelgen.structure.StructureCheck;
#endif
public final class ThreadedParameters
{
private static final ThreadLocal<ThreadedParameters> localParam = new ThreadLocal<ThreadedParameters>();
final ServerLevel level;
public WorldGenStructFeatManager structFeat = null;
#if POST_MC_1_18_1
public final StructureCheck structCheck;
#endif
boolean isValid = true;
public final PerfCalculator perf = new PerfCalculator();
public static ThreadedParameters getOrMake(GlobalParameters param)
{
ThreadedParameters tParam = localParam.get();
if (tParam != null && tParam.isValid && tParam.level == param.level)
return tParam;
tParam = new ThreadedParameters(param);
localParam.set(tParam);
return tParam;
}
public void markAsInvalid()
{
isValid = false;
}
private ThreadedParameters(GlobalParameters param)
{
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,
param.level.dimension(), param.generator, level, param.generator.getBiomeSource(), param.worldSeed,
param.fixerUpper);
#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, GlobalParameters param)
{
structFeat = new WorldGenStructFeatManager(param.worldGenSettings, genLevel #if POST_MC_1_18_1, structCheck #endif);
}
}
@@ -1,296 +0,0 @@
/*
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
* licensed under the GNU GPL 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 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.worldGeneration.mimicObject;
import com.google.common.collect.Maps;
import com.mojang.serialization.Codec;
import com.mojang.serialization.Dynamic;
import com.seibel.lod.common.wrappers.worldGeneration.BatchGenerationEnvironment;
import com.seibel.lod.core.api.ApiShared;
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 net.minecraft.core.Registry;
import net.minecraft.core.SectionPos;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.ListTag;
import net.minecraft.nbt.NbtOps;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.level.*;
import net.minecraft.world.level.biome.Biome;
import net.minecraft.world.level.biome.Biomes;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.chunk.*;
import net.minecraft.world.level.chunk.storage.ChunkSerializer;
import net.minecraft.world.level.levelgen.Heightmap;
#if POST_MC_1_18_1
import net.minecraft.world.level.levelgen.blending.BlendingData;
#if PRE_MC_1_19
import net.minecraft.world.level.levelgen.feature.StructureFeature;
#endif
import net.minecraft.world.level.levelgen.structure.StructureStart;
import net.minecraft.world.level.levelgen.structure.pieces.StructurePieceSerializationContext;
import net.minecraft.world.ticks.LevelChunkTicks;
#endif
#if POST_MC_1_18_2
import net.minecraft.core.Holder;
import net.minecraft.core.RegistryAccess;
#if PRE_MC_1_19
import net.minecraft.world.level.levelgen.feature.ConfiguredStructureFeature;
#endif
#endif
import net.minecraft.world.level.lighting.LevelLightEngine;
import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.level.material.Fluids;
import org.apache.logging.log4j.Logger;
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());
#endif
private static final String TAG_UPGRADE_DATA = "UpgradeData";
private static final String BLOCK_TICKS_TAG_18 = "block_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)
{
BlendingData blendingData = null;
if (chunkData.contains("blending_data", 10))
{
@SuppressWarnings({ "unchecked", "rawtypes" })
Dynamic<CompoundTag> blendingDataTag = new Dynamic(NbtOps.INSTANCE, chunkData.getCompound("blending_data"));
blendingData = BlendingData.CODEC.parse(blendingDataTag).resultOrPartial(LOGGER::error).orElse(null);
}
return blendingData;
}
#endif
private static LevelChunkSection[] readSections(LevelAccessor level, LevelLightEngine lightEngine, ChunkPos chunkPos, CompoundTag chunkData)
{
#if POST_MC_1_18_1
Registry<Biome> biomes = level.registryAccess().registryOrThrow(Registry.BIOME_REGISTRY);
#if PRE_MC_1_18_2
Codec<PalettedContainer<Biome>> biomeCodec = PalettedContainer.codec(
biomes, biomes.byNameCodec(), PalettedContainer.Strategy.SECTION_BIOMES, biomes.getOrThrow(Biomes.PLAINS));
#elif PRE_MC_1_19
Codec<PalettedContainer<Holder<Biome>>> biomeCodec = PalettedContainer.codec(
biomes.asHolderIdMap(), biomes.holderByNameCodec(), PalettedContainer.Strategy.SECTION_BIOMES, biomes.getHolderOrThrow(Biomes.PLAINS));
#else
Codec<PalettedContainer<Holder<Biome>>> biomeCodec = PalettedContainer.codecRW(
biomes.asHolderIdMap(), biomes.holderByNameCodec(), PalettedContainer.Strategy.SECTION_BIOMES, biomes.getHolderOrThrow(Biomes.PLAINS));
#endif
#endif
int i = #if PRE_MC_1_17_1 16; #else level.getSectionsCount(); #endif
LevelChunkSection[] chunkSections = new LevelChunkSection[i];
boolean isLightOn = chunkData.getBoolean("isLightOn");
boolean hasSkyLight = level.dimensionType().hasSkyLight();
ListTag tagSections = chunkData.getList("Sections", 10);
if (tagSections.isEmpty()) tagSections = chunkData.getList("sections", 10);
for (int j = 0; j < tagSections.size(); ++j)
{
CompoundTag tagSection = tagSections.getCompound(j);
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);
if (sectionId >= 0 && sectionId < chunkSections.length)
{
PalettedContainer<BlockState> blockStateContainer;
#if PRE_MC_1_18_2
PalettedContainer<Biome> biomeContainer;
#else
PalettedContainer<Holder<Biome>> biomeContainer;
#endif
blockStateContainer = tagSection.contains("block_states", 10)
? BLOCK_STATE_CODEC.parse(NbtOps.INSTANCE, tagSection.getCompound("block_states")).promotePartial(string -> logErrors(chunkPos, sectionYPos, string)).getOrThrow(false, LOGGER::error)
: new PalettedContainer<BlockState>(Block.BLOCK_STATE_REGISTRY, Blocks.AIR.defaultBlockState(), PalettedContainer.Strategy.SECTION_STATES);
#if PRE_MC_1_18_2
biomeContainer = tagSection.contains("biomes", 10)
? biomeCodec.parse(NbtOps.INSTANCE, tagSection.getCompound("biomes")).promotePartial(string -> logErrors(chunkPos, sectionYPos, string)).getOrThrow(false, LOGGER::error)
: new PalettedContainer<Biome>(biomes, biomes.getOrThrow(Biomes.PLAINS), PalettedContainer.Strategy.SECTION_BIOMES);
#else
biomeContainer = tagSection.contains("biomes", 10)
? biomeCodec.parse(NbtOps.INSTANCE, tagSection.getCompound("biomes")).promotePartial(string -> logErrors(chunkPos, i, (String) string)).getOrThrow(false, LOGGER::error)
: new PalettedContainer<Holder<Biome>>(biomes.asHolderIdMap(), biomes.getHolderOrThrow(Biomes.PLAINS), PalettedContainer.Strategy.SECTION_BIOMES);
#endif
chunkSections[sectionId] = new LevelChunkSection(sectionYPos, blockStateContainer, biomeContainer);
}
#endif
if (!isLightOn) continue;
if (tagSection.contains("BlockLight", 7))
lightEngine.queueSectionData(LightLayer.BLOCK, SectionPos.of(chunkPos, sectionYPos),
new DataLayer(tagSection.getByteArray("BlockLight")), true);
if (hasSkyLight && tagSection.contains("SkyLight", 7))
lightEngine.queueSectionData(LightLayer.SKY, SectionPos.of(chunkPos, sectionYPos),
new DataLayer(tagSection.getByteArray("SkyLight")), true);
}
return chunkSections;
}
private static void readHeightmaps(LevelChunk chunk, CompoundTag chunkData)
{
CompoundTag tagHeightmaps = chunkData.getCompound("Heightmaps");
for (Heightmap.Types type : ChunkStatus.FULL.heightmapsAfter())
{
String heightmap = type.getSerializationKey();
if (tagHeightmaps.contains(heightmap, 12))
chunk.setHeightmap(type, tagHeightmaps.getLongArray(heightmap));
}
Heightmap.primeHeightmaps(chunk, ChunkStatus.FULL.heightmapsAfter());
}
private static void readPostPocessings(LevelChunk chunk, CompoundTag chunkData)
{
ListTag tagPostProcessings = chunkData.getList("PostProcessing", 9);
for (int n = 0; n < tagPostProcessings.size(); ++n)
{
ListTag listTag3 = tagPostProcessings.getList(n);
for (int o = 0; o < listTag3.size(); ++o)
{
chunk.addPackedPostProcess(listTag3.getShort(o), n);
}
}
}
public static ChunkStatus.ChunkType readChunkType(CompoundTag tagLevel)
{
ChunkStatus chunkStatus = ChunkStatus.byName(tagLevel.getString("Status"));
if (chunkStatus != null) {
return chunkStatus.getChunkType();
}
return ChunkStatus.ChunkType.PROTOCHUNK;
}
public static LevelChunk read(WorldGenLevel level, LevelLightEngine lightEngine, ChunkPos chunkPos, CompoundTag chunkData)
{
#if PRE_MC_1_18_1
CompoundTag tagLevel = chunkData.getCompound("Level");
#else
CompoundTag tagLevel = chunkData;
#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;
}
ChunkStatus.ChunkType chunkType = readChunkType(tagLevel);
#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()))
return null;
#else
if (chunkType == ChunkStatus.ChunkType.PROTOCHUNK && (blendingData == null || level.getChunk(chunkPos.getMiddleBlockX(),chunkPos.getMiddleBlockZ()).isOldNoiseGeneration()))
return null;
#endif
#endif
long inhabitedTime = tagLevel.getLong("InhabitedTime");
//================== 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;
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);
LevelChunkTicks<Fluid> fluidTicks = LevelChunkTicks.load(tagLevel.getList(FLUID_TICKS_TAG_18, 10),
string -> Registry.FLUID.getOptional(ResourceLocation.tryParse(string)), chunkPos);
#endif
LevelChunkSection[] levelChunkSections = readSections(level, lightEngine, chunkPos, tagLevel);
// ====================== 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
chunk.setLightCorrect(isLightOn);
readHeightmaps(chunk, chunkData);
readPostPocessings(chunk, chunkData);
return chunk;
}
private static void logErrors(ChunkPos chunkPos, int i, String string)
{
LOGGER.error("Distant Horizons: Recoverable errors when loading section [" + chunkPos.x + ", " + i + ", " + chunkPos.z + "]: " + string);
}
}
@@ -1,64 +0,0 @@
/*
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
* licensed under the GNU GPL 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 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.worldGeneration.mimicObject;
import com.seibel.lod.core.handlers.dependencyInjection.ModAccessorHandler;
import com.seibel.lod.core.wrapperInterfaces.modAccessor.IStarlightAccessor;
import net.minecraft.world.level.BlockGetter;
#if POST_MC_1_17_1
import net.minecraft.world.level.LevelHeightAccessor;
#endif
import net.minecraft.world.level.chunk.ChunkStatus;
import net.minecraft.world.level.chunk.LightChunkGetter;
public class LightGetterAdaptor implements LightChunkGetter {
private final BlockGetter heightGetter;
public LightedWorldGenRegion genRegion = null;
final boolean shouldReturnNull;
public LightGetterAdaptor(BlockGetter heightAccessor) {
this.heightGetter = heightAccessor;
shouldReturnNull = ModAccessorHandler.get(IStarlightAccessor.class) != null;
}
public void setRegion(LightedWorldGenRegion region) {
genRegion = region;
}
@Override
public BlockGetter getChunkForLighting(int chunkX, int chunkZ) {
if (genRegion == null)
throw new IllegalStateException("World Gen region has not been set!");
// May be null
return genRegion.getChunk(chunkX, chunkZ, ChunkStatus.EMPTY, false);
}
@Override
public BlockGetter getLevel() {
return shouldReturnNull ? null : (genRegion != null ? genRegion : heightGetter);
}
#if POST_MC_1_17_1
public LevelHeightAccessor getLevelHeightAccessor() {
return heightGetter;
}
#endif
}
@@ -1,319 +0,0 @@
/*
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
* licensed under the GNU GPL 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 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.worldGeneration.mimicObject;
import java.util.List;
import com.seibel.lod.core.api.ApiShared;
import org.jetbrains.annotations.Nullable;
import com.seibel.lod.common.wrappers.worldGeneration.BatchGenerationEnvironment.EmptyChunkGenerator;
import com.seibel.lod.core.enums.config.LightGenerationMode;
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.color.block.BlockTintCache;
import net.minecraft.client.renderer.BiomeColors;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Cursor3D;
import net.minecraft.core.SectionPos;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.WorldGenRegion;
import net.minecraft.util.Mth;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.ChunkPos;
import net.minecraft.world.level.ColorResolver;
#if POST_MC_1_17_1
import net.minecraft.world.level.LevelHeightAccessor;
#endif
import net.minecraft.world.level.LightLayer;
#if PRE_MC_1_19
import net.minecraft.world.level.StructureFeatureManager;
import net.minecraft.world.level.levelgen.feature.StructureFeature;
#endif
import net.minecraft.world.level.biome.Biome;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.chunk.ChunkAccess;
import net.minecraft.world.level.chunk.ChunkStatus;
import net.minecraft.world.level.chunk.ImposterProtoChunk;
import net.minecraft.world.level.chunk.LevelChunk;
import net.minecraft.world.level.levelgen.Heightmap;
import net.minecraft.world.level.levelgen.structure.StructureStart;
import net.minecraft.world.level.lighting.LevelLightEngine;
public class LightedWorldGenRegion extends WorldGenRegion {
public final WorldGenLevelLightEngine light;
public final LightGenerationMode lightMode;
public final EmptyChunkGenerator generator;
public final int writeRadius;
public final int size;
private final ChunkPos firstPos;
private final List<ChunkAccess> cache;
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,
List<ChunkAccess> list, ChunkStatus chunkStatus, int i,
LightGenerationMode lightMode, EmptyChunkGenerator generator) {
super(serverLevel, list #if POST_MC_1_17_1, chunkStatus, i #endif);
this.lightMode = lightMode;
this.firstPos = list.get(0).getPos();
this.generator = generator;
light = lightEngine;
writeRadius = i;
cache = list;
size = Mth.floor(Math.sqrt(list.size()));
}
#if POST_MC_1_17_1
// Bypass BCLib mixin overrides.
@Override
public boolean ensureCanWrite(BlockPos blockPos) {
int i = SectionPos.blockToSectionCoord(blockPos.getX());
int j = SectionPos.blockToSectionCoord(blockPos.getZ());
ChunkPos chunkPos = this.getCenter();
ChunkAccess center = this.getChunk(chunkPos.x, chunkPos.z);
int k = Math.abs(chunkPos.x - i);
int l = Math.abs(chunkPos.z - j);
if (k > this.writeRadius || l > this.writeRadius) {
return false;
}
#if POST_MC_1_18_1
if (center.isUpgrading()) {
LevelHeightAccessor levelHeightAccessor = center.getHeightAccessorForGeneration();
if (blockPos.getY() < levelHeightAccessor.getMinBuildHeight() || blockPos.getY() >= levelHeightAccessor.getMaxBuildHeight()) {
return false;
}
}
#endif
return true;
}
#endif
// TODO Check this
// @Override
// public List<? extends StructureStart<?>> startsForFeature(SectionPos sectionPos,
// StructureFeature<?> structureFeature) {
// return structFeat.startsForFeature(sectionPos, structureFeature);
// }
// Skip updating the related tile entities
@Override
public boolean setBlock(BlockPos blockPos, BlockState blockState, int i, int j) {
ChunkAccess chunkAccess = this.getChunk(blockPos);
if (chunkAccess instanceof LevelChunk)
return true;
chunkAccess.setBlockState(blockPos, blockState, false);
// This is for post ticking for water on gen and stuff like that. Not enabled
// for now.
// if (blockState.hasPostProcess(this, blockPos))
// this.getChunk(blockPos).markPosForPostprocessing(blockPos);
return true;
}
// Skip Dropping the item on destroy
@Override
public boolean destroyBlock(BlockPos blockPos, boolean bl, @Nullable Entity entity, int i) {
BlockState blockState = this.getBlockState(blockPos);
if (blockState.isAir()) {
return false;
}
return this.setBlock(blockPos, Blocks.AIR.defaultBlockState(), 3, i);
}
// Skip BlockEntity stuff. It aren't really needed
@Override
public BlockEntity getBlockEntity(BlockPos blockPos) {
return null;
}
// Skip BlockEntity stuff. It aren't really needed
@Override
public boolean addFreshEntity(Entity entity) {
return true;
}
// Allays have empty chunks even if it's outside the worldGenRegion
// @Override
// public boolean hasChunk(int i, int j) {
// return true;
// }
// Override to ensure no other mod mixins cause skipping the overrided
// getChunk(...)
@Override
public ChunkAccess getChunk(int i, int j) {
return this.getChunk(i, j, ChunkStatus.EMPTY);
}
// Override to ensure no other mod mixins cause skipping the overrided
// getChunk(...)
@Override
public ChunkAccess getChunk(int i, int j, ChunkStatus chunkStatus) {
return this.getChunk(i, j, chunkStatus, true);
}
// Use this instead of super.getChunk() to bypass C2ME concurrency checks
private ChunkAccess superGetChunk(int x, int z, ChunkStatus cs) {
int k = x - firstPos.x;
int l = z - firstPos.z;
return cache.get(k + l * size);
}
// Use this instead of super.hasChunk() to bypass C2ME concurrency checks
private boolean superHasChunk(int x, int z) {
int k = x - firstPos.x;
int l = z - firstPos.z;
return l >= 0 && l < size && k >= 0 && k < size;
}
// Allow creating empty chunks even if it's outside the worldGenRegion
@Override
@Nullable
public ChunkAccess getChunk(int i, int j, ChunkStatus chunkStatus, boolean bl) {
ChunkAccess chunk = getChunkAccess(i, j, chunkStatus, bl);
if (chunk instanceof LevelChunk) {
chunk = new ImposterProtoChunk((LevelChunk) chunk #if POST_MC_1_18_1, true #endif);
}
return chunk;
}
private static ChunkStatus debugTriggeredForStatus = null;
private ChunkAccess getChunkAccess(int i, int j, ChunkStatus chunkStatus, boolean bl) {
ChunkAccess chunk = superHasChunk(i, j) ? superGetChunk(i, j, ChunkStatus.EMPTY) : null;
if (chunk != null && chunk.getStatus().isOrAfter(chunkStatus)) {
return chunk;
}
if (!bl)
return null;
if (chunk == null) {
chunk = chunkMap.get(ChunkPos.asLong(i, j));
if (chunk == null) {
chunk = generator.generate(i, j);
if (chunk == null)
throw new NullPointerException("The provided generator should not return null!");
chunkMap.put(ChunkPos.asLong(i, j), chunk);
}
}
if (chunkStatus != ChunkStatus.EMPTY && chunkStatus != debugTriggeredForStatus) {
ApiShared.LOGGER.info("WorldGen requiring " + chunkStatus
+ " outside expected range detected. Force passing EMPTY chunk and seeing if it works.");
debugTriggeredForStatus = chunkStatus;
}
return chunk;
}
// Override force use of my own light engine
@Override
public LevelLightEngine getLightEngine() {
return light;
}
// Override force use of my own light engine
@Override
public int getBrightness(LightLayer lightLayer, BlockPos blockPos) {
if (lightMode != LightGenerationMode.FAST) {
return light.getLayerListener(lightLayer).getLightValue(blockPos);
}
if (lightLayer == LightLayer.BLOCK)
return 0;
BlockPos p = super.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, blockPos);
return (p.getY() <= blockPos.getY()) ? getMaxLightLevel() : 0;
}
// Override force use of my own light engine
@Override
public int getRawBrightness(BlockPos blockPos, int i) {
if (lightMode != LightGenerationMode.FAST) {
return light.getRawBrightness(blockPos, i);
}
BlockPos p = super.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, blockPos);
return (p.getY() <= blockPos.getY()) ? getMaxLightLevel() : 0;
}
// Override force use of my own light engine
@Override
public boolean canSeeSky(BlockPos blockPos) {
return (getBrightness(LightLayer.SKY, blockPos) >= getMaxLightLevel());
}
public int getBlockTint(BlockPos blockPos, ColorResolver colorResolver)
{
return calculateBlockTint(blockPos, colorResolver);
}
private Biome _getBiome(BlockPos pos) {
#if POST_MC_1_18_2
return getBiome(pos).value();
#else
return getBiome(pos);
#endif
}
public int calculateBlockTint(BlockPos blockPos, ColorResolver colorResolver)
{
#if PRE_MC_1_19
int i = (Minecraft.getInstance()).options.biomeBlendRadius;
#else
int i = (Minecraft.getInstance()).options.biomeBlendRadius().get();
#endif
if (i == 0)
return colorResolver.getColor((Biome) _getBiome(blockPos), blockPos.getX(), blockPos.getZ());
int j = (i * 2 + 1) * (i * 2 + 1);
int k = 0;
int l = 0;
int m = 0;
Cursor3D cursor3D = new Cursor3D(blockPos.getX() - i, blockPos.getY(), blockPos.getZ() - i, blockPos.getX() + i, blockPos.getY(), blockPos.getZ() + i);
BlockPos.MutableBlockPos mutableBlockPos = new BlockPos.MutableBlockPos();
while (cursor3D.advance())
{
mutableBlockPos.set(cursor3D.nextX(), cursor3D.nextY(), cursor3D.nextZ());
int n = colorResolver.getColor((Biome) _getBiome((BlockPos) 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;
}
}
@@ -1,221 +0,0 @@
/*
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
* licensed under the GNU GPL 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 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.worldGeneration.mimicObject;
import org.jetbrains.annotations.Nullable;
import net.minecraft.core.BlockPos;
import net.minecraft.core.SectionPos;
import net.minecraft.world.level.ChunkPos;
#if POST_MC_1_17_1
import net.minecraft.world.level.LevelHeightAccessor;
#endif
import net.minecraft.world.level.LightLayer;
import net.minecraft.world.level.chunk.ChunkAccess;
import net.minecraft.world.level.chunk.DataLayer;
import net.minecraft.world.level.chunk.LevelChunkSection;
import net.minecraft.world.level.lighting.BlockLightEngine;
import net.minecraft.world.level.lighting.LayerLightEventListener;
import net.minecraft.world.level.lighting.LevelLightEngine;
import net.minecraft.world.level.lighting.SkyLightEngine;
public class WorldGenLevelLightEngine extends LevelLightEngine {
public static final int MAX_SOURCE_LEVEL = 15;
public static final int LIGHT_SECTION_PADDING = 1;
#if POST_MC_1_17_1
protected final LevelHeightAccessor levelHeightAccessor;
#endif
@Nullable
public final BlockLightEngine blockEngine;
@Nullable
public final SkyLightEngine skyEngine;
public WorldGenLevelLightEngine(LightGetterAdaptor genRegion) {
super(genRegion, false, false);
#if POST_MC_1_17_1
this.levelHeightAccessor = genRegion.getLevelHeightAccessor();
#endif
this.blockEngine = new BlockLightEngine(genRegion);
this.skyEngine = new SkyLightEngine(genRegion);
}
@Override
public void checkBlock(BlockPos blockPos) {
if (this.blockEngine != null) {
this.blockEngine.checkBlock(blockPos);
}
if (this.skyEngine != null) {
this.skyEngine.checkBlock(blockPos);
}
}
@Override
public void onBlockEmissionIncrease(BlockPos blockPos, int i) {
if (this.blockEngine != null) {
this.blockEngine.onBlockEmissionIncrease(blockPos, i);
}
}
@Override
public boolean hasLightWork() {
if (this.skyEngine != null && this.skyEngine.hasLightWork()) {
return true;
}
return this.blockEngine != null && this.blockEngine.hasLightWork();
}
@Override
public int runUpdates(int i, boolean bl, boolean bl2) {
if (this.blockEngine != null && this.skyEngine != null) {
int j = i / 2;
int k = this.blockEngine.runUpdates(j, bl, bl2);
int l = i - j + k;
int m = this.skyEngine.runUpdates(l, bl, bl2);
if (k == 0 && m > 0) {
return this.blockEngine.runUpdates(m, bl, bl2);
}
return m;
}
if (this.blockEngine != null) {
return this.blockEngine.runUpdates(i, bl, bl2);
}
if (this.skyEngine != null) {
return this.skyEngine.runUpdates(i, bl, bl2);
}
return i;
}
@Override
public void updateSectionStatus(SectionPos sectionPos, boolean bl) {
if (this.blockEngine != null) {
this.blockEngine.updateSectionStatus(sectionPos, bl);
}
if (this.skyEngine != null) {
this.skyEngine.updateSectionStatus(sectionPos, bl);
}
}
@Override
public void enableLightSources(ChunkPos chunkPos, boolean bl) {
if (this.blockEngine != null) {
this.blockEngine.enableLightSources(chunkPos, bl);
}
if (this.skyEngine != null) {
this.skyEngine.enableLightSources(chunkPos, bl);
}
}
@Override
public LayerLightEventListener getLayerListener(LightLayer lightLayer) {
if (lightLayer == LightLayer.BLOCK) {
if (this.blockEngine == null) {
return LayerLightEventListener.DummyLightLayerEventListener.INSTANCE;
}
return this.blockEngine;
}
if (this.skyEngine == null) {
return LayerLightEventListener.DummyLightLayerEventListener.INSTANCE;
}
return this.skyEngine;
}
@Override
public int getRawBrightness(BlockPos blockPos, int i) {
int j = this.skyEngine == null ? 0 : this.skyEngine.getLightValue(blockPos) - i;
int k = this.blockEngine == null ? 0 : this.blockEngine.getLightValue(blockPos);
return Math.max(k, j);
}
public void lightChunk(ChunkAccess chunkAccess, boolean needLightBlockUpdate) {
ChunkPos chunkPos = chunkAccess.getPos();
chunkAccess.setLightCorrect(false);
LevelChunkSection[] levelChunkSections = chunkAccess.getSections();
for (int i = 0; i <
#if POST_MC_1_17_1
chunkAccess.getSectionsCount()
#else
16
#endif
; ++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;
int j = this.levelHeightAccessor.getSectionYFromSectionIndex(i);
updateSectionStatus(SectionPos.of(chunkPos, j), false);
#endif
}
enableLightSources(chunkPos, true);
if (needLightBlockUpdate) {
chunkAccess.getLights().forEach(blockPos ->
onBlockEmissionIncrease(blockPos, chunkAccess.getLightEmission(blockPos)));
}
chunkAccess.setLightCorrect(true);
}
@Override
public String getDebugData(LightLayer lightLayer, SectionPos sectionPos) {
throw new UnsupportedOperationException("This should never be used!");
}
@Override
public void queueSectionData(LightLayer lightLayer, SectionPos sectionPos, @Nullable DataLayer dataLayer, boolean bl) {
if (lightLayer == LightLayer.BLOCK) {
if (this.blockEngine != null) {
this.blockEngine.queueSectionData(sectionPos.asLong(), dataLayer, bl);
}
} else if (this.skyEngine != null) {
this.skyEngine.queueSectionData(sectionPos.asLong(), dataLayer, bl);
}
}
@Override
public void retainData(ChunkPos chunkPos, boolean bl) {
if (this.blockEngine != null) {
this.blockEngine.retainData(chunkPos, bl);
}
if (this.skyEngine != null) {
this.skyEngine.retainData(chunkPos, bl);
}
}
#if POST_MC_1_17_1
@Override
public int getLightSectionCount() {
throw new UnsupportedOperationException("This should never be used!");
}
@Override
public int getMinLightSection() {
throw new UnsupportedOperationException("This should never be used!");
}
@Override
public int getMaxLightSection() {
throw new UnsupportedOperationException("This should never be used!");
}
#endif
}
@@ -1,228 +0,0 @@
/*
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
* licensed under the GNU GPL 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 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.worldGeneration.mimicObject;
import java.util.Iterator;
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 com.google.common.collect.ImmutableList;
import it.unimi.dsi.fastutil.longs.LongIterator;
import it.unimi.dsi.fastutil.longs.LongSet;
import net.minecraft.core.BlockPos;
import net.minecraft.core.SectionPos;
import net.minecraft.server.level.WorldGenRegion;
import net.minecraft.world.level.ChunkPos;
import net.minecraft.world.level.LevelAccessor;
import net.minecraft.world.level.WorldGenLevel;
import net.minecraft.world.level.chunk.ChunkAccess;
import net.minecraft.world.level.chunk.ChunkStatus;
import net.minecraft.world.level.levelgen.WorldGenSettings;
#if PRE_MC_1_19
import net.minecraft.world.level.levelgen.feature.ConfiguredStructureFeature;
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;
#endif
import net.minecraft.world.level.levelgen.structure.StructureStart;
#if PRE_MC_1_19
public class WorldGenStructFeatManager extends StructureFeatureManager {
#else
public class WorldGenStructFeatManager extends StructureManager {
#endif
final WorldGenLevel genLevel;
WorldGenSettings worldGenSettings;
#if POST_MC_1_18_1
StructureCheck structureCheck;
#endif
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.worldGenSettings = worldGenSettings;
}
@Override
public WorldGenStructFeatManager forWorldGenRegion(WorldGenRegion worldGenRegion) {
if (worldGenRegion == genLevel)
return this;
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
public Stream<? extends StructureStart<?>> startsForFeature(SectionPos sectionPos2,
StructureFeature<?> structureFeature) {
ChunkAccess chunk = _getChunk(sectionPos2.x(), sectionPos2.z(), ChunkStatus.STRUCTURE_REFERENCES);
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;
return chunk.hasAnyStructureReferences();
}
#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
}
@@ -1,85 +0,0 @@
/*
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
* licensed under the GNU GPL 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 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.worldGeneration.step;
import java.util.ArrayList;
import java.util.List;
import com.seibel.lod.common.wrappers.worldGeneration.BatchGenerationEnvironment;
import com.seibel.lod.common.wrappers.worldGeneration.ThreadedParameters;
import net.minecraft.core.Registry;
import net.minecraft.server.level.WorldGenRegion;
#if PRE_MC_1_19
import net.minecraft.world.level.StructureFeatureManager;
#endif
import net.minecraft.world.level.biome.Biome;
import net.minecraft.world.level.chunk.ChunkAccess;
import net.minecraft.world.level.chunk.ChunkGenerator;
import net.minecraft.world.level.chunk.ChunkStatus;
import net.minecraft.world.level.chunk.ProtoChunk;
import net.minecraft.world.level.levelgen.DebugLevelSource;
import net.minecraft.world.level.levelgen.FlatLevelSource;
import net.minecraft.world.level.levelgen.NoiseBasedChunkGenerator;
#if POST_MC_1_18_1
import net.minecraft.world.level.levelgen.blending.Blender;
#endif
public final class StepBiomes {
/**
*
*/
private final BatchGenerationEnvironment environment;
/**
* @param batchGenerationEnvironment
*/
public StepBiomes(BatchGenerationEnvironment batchGenerationEnvironment)
{
environment = batchGenerationEnvironment;
}
public final ChunkStatus STATUS = ChunkStatus.BIOMES;
public void generateGroup(ThreadedParameters tParams, WorldGenRegion worldGenRegion,
List<ChunkAccess> chunks) {
ArrayList<ChunkAccess> chunksToDo = new ArrayList<ChunkAccess>();
for (ChunkAccess chunk : chunks) {
if (chunk.getStatus().isOrAfter(STATUS)) continue;
((ProtoChunk) chunk).setStatus(STATUS);
chunksToDo.add(chunk);
}
for (ChunkAccess chunk : chunksToDo) {
// 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),
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
}
}
}
@@ -1,83 +0,0 @@
/*
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
* licensed under the GNU GPL 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 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.worldGeneration.step;
import java.util.ArrayList;
import com.seibel.lod.common.wrappers.worldGeneration.BatchGenerationEnvironment;
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 net.minecraft.ReportedException;
import net.minecraft.server.level.WorldGenRegion;
import net.minecraft.world.level.chunk.ChunkAccess;
import net.minecraft.world.level.chunk.ChunkStatus;
import net.minecraft.world.level.chunk.ProtoChunk;
import net.minecraft.world.level.levelgen.Heightmap;
#if POST_MC_1_18_1
import net.minecraft.world.level.levelgen.blending.Blender;
#endif
public final class StepFeatures {
/**
*
*/
private final BatchGenerationEnvironment environment;
/**
* @param batchGenerationEnvironment
*/
public StepFeatures(BatchGenerationEnvironment batchGenerationEnvironment)
{
environment = batchGenerationEnvironment;
}
public final ChunkStatus STATUS = ChunkStatus.FEATURES;
public void generateGroup(ThreadedParameters tParams, LightedWorldGenRegion worldGenRegion,
ArrayGridList<ChunkAccess> chunks) {
ArrayList<ChunkAccess> chunksToDo = new ArrayList<ChunkAccess>();
for (ChunkAccess chunk : chunks) {
if (chunk.getStatus().isOrAfter(STATUS)) continue;
((ProtoChunk) chunk).setStatus(STATUS);
chunksToDo.add(chunk);
}
for (ChunkAccess chunk : chunksToDo) {
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,
tParams.structFeat.forWorldGenRegion(worldGenRegion));
#endif
} catch (ReportedException e) {
e.printStackTrace();
// FIXME: Features concurrent modification issue. Something about cocobeans might just
// error out. For now just retry.
}
}
}
}
@@ -1,83 +0,0 @@
/*
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
* licensed under the GNU GPL 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 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.worldGeneration.step;
import com.seibel.lod.common.wrappers.worldGeneration.BatchGenerationEnvironment;
import com.seibel.lod.common.wrappers.worldGeneration.mimicObject.WorldGenLevelLightEngine;
import com.seibel.lod.core.util.gridList.ArrayGridList;
import net.minecraft.server.level.ThreadedLevelLightEngine;
import net.minecraft.world.level.chunk.ChunkAccess;
import net.minecraft.world.level.chunk.ChunkStatus;
import net.minecraft.world.level.chunk.LevelChunk;
import net.minecraft.world.level.chunk.ProtoChunk;
import net.minecraft.world.level.lighting.LevelLightEngine;
import net.minecraft.world.level.lighting.LightEventListener;
public final class StepLight {
/**
*
*/
private final BatchGenerationEnvironment environment;
/**
* @param batchGenerationEnvironment
*/
public StepLight(BatchGenerationEnvironment batchGenerationEnvironment)
{
environment = batchGenerationEnvironment;
}
public final ChunkStatus STATUS = ChunkStatus.LIGHT;
public void generateGroup(
#if PRE_MC_1_17_1 LevelLightEngine lightEngine,
#else LightEventListener lightEngine, #endif
ArrayGridList<ChunkAccess> chunks) {
for (ChunkAccess chunk : chunks) {
if (chunk.getStatus().isOrAfter(STATUS)) continue;
((ProtoChunk) chunk).setStatus(STATUS);
}
for (ChunkAccess chunk : chunks) {
boolean hasCorrectBlockLight = (chunk instanceof LevelChunk && chunk.isLightCorrect());
try {
if (lightEngine == null) {
// Do nothing
} else if (lightEngine instanceof WorldGenLevelLightEngine) {
((WorldGenLevelLightEngine)lightEngine).lightChunk(chunk, !hasCorrectBlockLight);
} else if (lightEngine instanceof ThreadedLevelLightEngine) {
((ThreadedLevelLightEngine) lightEngine).lightChunk(chunk, !hasCorrectBlockLight).join();
} else {
assert(false);
}
} catch (Exception e) {
e.printStackTrace();
}
#if POST_MC_1_18_1
if (chunk instanceof LevelChunk) ((LevelChunk)chunk).setClientLightReady(true);
#endif
chunk.setLightCorrect(true);
}
lightEngine.runUpdates(Integer.MAX_VALUE, true, true);
}
}
@@ -1,94 +0,0 @@
/*
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
* licensed under the GNU GPL 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 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.worldGeneration.step;
import java.util.ArrayList;
import java.util.HashSet;
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.ThreadedParameters;
import com.seibel.lod.core.util.LodUtil;
import net.minecraft.server.level.WorldGenRegion;
import net.minecraft.util.Mth;
#if POST_MC_1_17_1
import net.minecraft.world.level.LevelHeightAccessor;
#endif
#if PRE_MC_1_19
import net.minecraft.world.level.StructureFeatureManager;
#endif
import net.minecraft.world.level.chunk.ChunkAccess;
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.levelgen.NoiseBasedChunkGenerator;
import net.minecraft.world.level.levelgen.NoiseSettings;
#if POST_MC_1_18_1
import net.minecraft.world.level.levelgen.blending.Blender;
#endif
public final class StepNoise {
/**
*
*/
private final BatchGenerationEnvironment environment;
/**
* @param batchGenerationEnvironment
*/
public StepNoise(BatchGenerationEnvironment batchGenerationEnvironment)
{
environment = batchGenerationEnvironment;
}
public final ChunkStatus STATUS = ChunkStatus.NOISE;
public void generateGroup(ThreadedParameters tParams, WorldGenRegion worldGenRegion,
List<ChunkAccess> chunks) {
ArrayList<ChunkAccess> chunksToDo = new ArrayList<ChunkAccess>();
for (ChunkAccess chunk : chunks) {
if (chunk.getStatus().isOrAfter(STATUS)) continue;
((ProtoChunk) chunk).setStatus(STATUS);
chunksToDo.add(chunk);
}
for (ChunkAccess chunk : chunksToDo) {
// 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),
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
LodUtil.checkInterruptsUnchecked(); // Speed up termination responsiveness
}
}
}
@@ -1,75 +0,0 @@
/*
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
* licensed under the GNU GPL 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 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.worldGeneration.step;
import java.util.ArrayList;
import java.util.List;
import com.seibel.lod.common.wrappers.worldGeneration.BatchGenerationEnvironment;
import com.seibel.lod.common.wrappers.worldGeneration.ThreadedParameters;
import net.minecraft.CrashReport;
import net.minecraft.CrashReportCategory;
import net.minecraft.ReportedException;
import net.minecraft.core.Registry;
import net.minecraft.core.SectionPos;
import net.minecraft.server.level.WorldGenRegion;
import net.minecraft.world.level.ChunkPos;
#if PRE_MC_1_19
import net.minecraft.world.level.StructureFeatureManager;
#endif
import net.minecraft.world.level.chunk.ChunkAccess;
import net.minecraft.world.level.chunk.ChunkStatus;
import net.minecraft.world.level.chunk.ProtoChunk;
import net.minecraft.world.level.levelgen.structure.StructureStart;
public final class StepStructureReference {
/**
*
*/
private final BatchGenerationEnvironment environment;
/**
* @param batchGenerationEnvironment
*/
public StepStructureReference(BatchGenerationEnvironment batchGenerationEnvironment)
{
environment = batchGenerationEnvironment;
}
public final ChunkStatus STATUS = ChunkStatus.STRUCTURE_REFERENCES;
public void generateGroup(ThreadedParameters tParams, WorldGenRegion worldGenRegion,
List<ChunkAccess> chunks) {
ArrayList<ChunkAccess> chunksToDo = new ArrayList<ChunkAccess>();
for (ChunkAccess chunk : chunks) {
if (chunk.getStatus().isOrAfter(STATUS)) continue;
((ProtoChunk) chunk).setStatus(STATUS);
chunksToDo.add(chunk);
}
for (ChunkAccess chunk : chunksToDo) {
// System.out.println("StepStructureReference: "+chunk.getPos());
environment.params.generator.createReferences(worldGenRegion, tParams.structFeat.forWorldGenRegion(worldGenRegion), chunk);
}
}
}
@@ -1,97 +0,0 @@
/*
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
* licensed under the GNU GPL 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 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.worldGeneration.step;
import java.util.ArrayList;
import java.util.List;
import com.seibel.lod.common.wrappers.worldGeneration.BatchGenerationEnvironment;
import com.seibel.lod.common.wrappers.worldGeneration.ThreadedParameters;
import net.minecraft.server.level.WorldGenRegion;
import net.minecraft.world.level.chunk.ChunkAccess;
import net.minecraft.world.level.chunk.ChunkStatus;
import net.minecraft.world.level.chunk.ProtoChunk;
public final class StepStructureStart {
/**
*
*/
private final BatchGenerationEnvironment environment;
/**
* @param batchGenerationEnvironment
*/
public StepStructureStart(BatchGenerationEnvironment batchGenerationEnvironment)
{
environment = batchGenerationEnvironment;
}
public final ChunkStatus STATUS = ChunkStatus.STRUCTURE_STARTS;
public static class StructStartCorruptedException extends RuntimeException {
private static final long serialVersionUID = -8987434342051563358L;
public StructStartCorruptedException(ArrayIndexOutOfBoundsException e) {
super("StructStartCorruptedException");
super.initCause(e);
fillInStackTrace();
}
}
public void generateGroup(ThreadedParameters tParams, WorldGenRegion worldGenRegion,
List<ChunkAccess> chunks) {
ArrayList<ChunkAccess> chunksToDo = new ArrayList<ChunkAccess>();
for (ChunkAccess chunk : chunks) {
if (chunk.getStatus().isOrAfter(STATUS)) continue;
((ProtoChunk) chunk).setStatus(STATUS);
chunksToDo.add(chunk);
}
#if PRE_MC_1_19
if (environment.params.worldGenSettings.generateFeatures()) {
#elif POST_MC_1_19
if (environment.params.worldGenSettings.generateStructures()) {
#endif
for (ChunkAccess chunk : chunksToDo) {
// 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.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 {
tParams.structCheck.onStructureLoad(chunk.getPos(), chunk.getAllStarts());
} catch (ArrayIndexOutOfBoundsException e) {
// 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.
// TODO: Figure out in the future why this happens even though I am using new structFeat
throw new StepStructureStart.StructStartCorruptedException(e);
}
#endif
}
}
}
}
@@ -1,70 +0,0 @@
/*
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
* licensed under the GNU GPL 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 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.worldGeneration.step;
import java.util.ArrayList;
import java.util.List;
import com.seibel.lod.common.wrappers.worldGeneration.BatchGenerationEnvironment;
import com.seibel.lod.common.wrappers.worldGeneration.ThreadedParameters;
import net.minecraft.server.level.WorldGenRegion;
import net.minecraft.world.level.chunk.ChunkAccess;
import net.minecraft.world.level.chunk.ChunkStatus;
import net.minecraft.world.level.chunk.ProtoChunk;
public final class StepSurface {
/**
*
*/
private final BatchGenerationEnvironment environment;
/**
* @param batchGenerationEnvironment
*/
public StepSurface(BatchGenerationEnvironment batchGenerationEnvironment)
{
environment = batchGenerationEnvironment;
}
public final ChunkStatus STATUS = ChunkStatus.SURFACE;
public void generateGroup(ThreadedParameters tParams, WorldGenRegion worldGenRegion,
List<ChunkAccess> chunks) {
ArrayList<ChunkAccess> chunksToDo = new ArrayList<ChunkAccess>();
for (ChunkAccess chunk : chunks) {
if (chunk.getStatus().isOrAfter(STATUS)) continue;
((ProtoChunk) chunk).setStatus(STATUS);
chunksToDo.add(chunk);
}
for (ChunkAccess chunk : chunksToDo) {
// System.out.println("StepSurface: "+chunk.getPos());
#if PRE_MC_1_18_1
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
}
}
}
@@ -1,45 +0,0 @@
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
@@ -1,48 +0,0 @@
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
@@ -1,50 +0,0 @@
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
# 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/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 doFill (Lnet/minecraft/world/level/levelgen/blending/Blender;Lnet/minecraft/world/level/StructureFeatureManager;Lnet/minecraft/world/level/chunk/ChunkAccess;II)Lnet/minecraft/world/level/chunk/ChunkAccess;
#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
# hacky stuff
accessible field net/minecraft/util/ThreadingDetector lock Ljava/util/concurrent/Semaphore;
mutable field net/minecraft/util/ThreadingDetector lock Ljava/util/concurrent/Semaphore;
@@ -1,47 +0,0 @@
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;
Submodule core deleted from f00a1db9c2
-343
View File
@@ -1,343 +0,0 @@
plugins {
id "com.github.johnrengelman.shadow" version "7.1.0"
}
// From parent
apply plugin: "java"
apply plugin: "architectury-plugin"
apply plugin: "maven-publish"
apply plugin: "dev.architectury.loom"
archivesBaseName = rootProject.archives_base_name
version = rootProject.mod_version //FIXME: Redef
group = rootProject.maven_group
version = rootProject.mod_version+"-"+rootProject.minecraft_version+"-"+new Date().format("yyyy_MM_dd_HH_mm")
loom {
silentMojangMappingsLicense()
accessWidenerPath.set(project(":common").file("src/main/resources/${acsessWidenerVersion}.lod.accesswidener"))
}
architectury {
platformSetupLoomIde()
fabric()
}
configurations {
common
shadowMe
implementation.extendsFrom shadowMe
compileClasspath.extendsFrom common
runtimeClasspath.extendsFrom common
developmentFabric.extendsFrom common
addModJar
include.extendsFrom addModJar
modImplementation.extendsFrom addModJar
}
java {
withSourcesJar()
}
jar.dependsOn(project(":core").remapJar)
remapSourcesJar.dependsOn(project(":core").remapJar)
repositories {
// Required for ModMenu
maven { url "https://maven.terraformersmc.com/" }
mavenCentral()
// For parchment mappings
maven { url "https://maven.parchmentmc.org" }
// used to download and compile dependencies from git repos
maven { url 'https://jitpack.io' }
// For Manifold Preprocessor
maven { url 'https://oss.sonatype.org/content/repositories/snapshots/' }
// Required for importing Modrinth mods
maven {
name = "Modrinth"
url = "https://api.modrinth.com/maven"
content {
includeGroup "maven.modrinth"
}
}
// Required for importing CursedForge mods
maven {
url "https://www.cursemaven.com"
content {
includeGroup "curse.maven"
}
}
// These 2 are for importing mods that arnt on CursedForge, Modrinth, GitHub, GitLab or anywhere opensource
flatDir {
dirs "${rootDir}/mods/fabric"
content {
includeGroup "fabric-mod"
}
}
flatDir {
dirs "${rootDir}/mods/forge"
content {
includeGroup "forge-mod"
}
}
}
def addMod(path, enabled) {
if (enabled == "2")
dependencies { modImplementation(path) }
else if (enabled == "1")
dependencies { modCompileOnly(path) }
}
dependencies {
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)
if (rootProject.minecraft_version != "1.19" && rootProject.minecraft_version != "1.19.1")
parchment("org.parchmentmc.data:parchment-${rootProject.minecraft_version}:${rootProject.parchment_version}@zip")
else
parchment("org.parchmentmc.data:parchment-1.18.2:${rootProject.parchment_version}@zip") // As 1.19 dosnt have parchment mappings yet, we use 1.18.2 mapping
}
//Manifold
annotationProcessor "systems.manifold:manifold-preprocessor:${rootProject.manifold_version}"
// Toml
implementation("com.electronwill.night-config:toml:${rootProject.toml_version}")
// 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 unless working with fabric
modImplementation "net.fabricmc:fabric-loader:${rootProject.fabric_loader_version}"
common(project(":core"))
// Fabric loader
modImplementation "net.fabricmc:fabric-loader:${rootProject.fabric_loader_version}"
// Fabric API
addModJar(fabricApi.module("fabric-lifecycle-events-v1", rootProject.fabric_api_version))
addModJar(fabricApi.module("fabric-resource-loader-v0", rootProject.fabric_api_version))
addModJar(fabricApi.module("fabric-key-binding-api-v1", rootProject.fabric_api_version))
addModJar(fabricApi.module("fabric-networking-api-v1", rootProject.fabric_api_version))
addModJar(fabricApi.module("fabric-api-base", rootProject.fabric_api_version))
// Mod Menu
modImplementation("com.terraformersmc:modmenu:${rootProject.modmenu_version}")
// 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
addMod("curse.maven:sodium-394468:${rootProject.sodium_version}", rootProject.enable_sodium)
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
addMod("maven.modrinth:lithium:${rootProject.lithium_version}", rootProject.enable_lithium)
// Iris
addMod("maven.modrinth:iris:${rootProject.iris_version}", rootProject.enable_iris)
// BCLib
addMod("com.github.paulevsGitch:BCLib:${rootProject.bclib_version}", rootProject.enable_bclib)
// Immersive Portals
/*
modImplementation("com.github.qouteall.ImmersivePortalsMod:build:${rootProject.immersive_portals_version}") {
exclude(group: "net.fabricmc.fabric-api")
transitive(false)
}
modImplementation("com.github.qouteall.ImmersivePortalsMod:imm_ptl_core:${rootProject.immersive_portals_version}") {
exclude(group: "net.fabricmc.fabric-api")
transitive(false)
}
modImplementation("com.github.qouteall.ImmersivePortalsMod:q_misc_util:${rootProject.immersive_portals_version}") {
exclude(group: "net.fabricmc.fabric-api")
transitive(false)
}
*/
// Toml
shadowMe("com.electronwill.night-config:toml:${rootProject.toml_version}") {}
common(project(path: ":common", configuration: "namedElements")) { transitive false }
shadowMe(project(path: ":common", configuration: "transformProductionFabric")) { transitive false }
shadowMe files(project(":core").file("build/libs/DistantHorizons-${rootProject.mod_version}.jar"))
// Compression
common 'org.tukaani:xz:1.9'
common 'org.apache.commons:commons-compress:1.21'
shadowMe 'org.tukaani:xz:1.9'
shadowMe 'org.apache.commons:commons-compress:1.21'
}
task deleteResources(type: Delete) {
delete file("build/resources/main")
}
// Copies the correct accesswidener and renames it
task copyAccessWidener(type: Copy) {
from project(":common").file("src/main/resources/${rootProject.acsessWidenerVersion}.lod.accesswidener")
into(file("build/resources/main"))
rename "${rootProject.acsessWidenerVersion}.lod.accesswidener", "lod.accesswidener"
}
task copyCoreResources(type: Copy) {
from fileTree(project(":core").file("src/main/resources"))
into file("build/resources/main")
}
task copyCommonResources(type: Copy) {
from fileTree(project(":common").file("src/main/resources"))
into file("build/resources/main")
}
processResources {
dependsOn(copyCoreResources)
dependsOn(copyCommonResources)
dependsOn(copyAccessWidener)
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 replaceProperties = [
version : mod_version,
mod_name : mod_name,
authors : mod_authors,
description : mod_description,
homepage : mod_homepage,
source : mod_source,
issues : mod_issues,
minecraft_version : minecraft_version,
compatible_minecraft_versions: compatible_minecraft_versions,
java_version : java_version
]
// 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
replaceProperties.put 'project', project
filesMatching(resourceTargets) {
expand replaceProperties
}
intoTargets.each { target ->
if (file(target).exists()) {
copy {
from(sourceSets.main.resources) {
include resourceTargets
expand replaceProperties
}
into target
}
}
}
}
runClient {
dependsOn(copyCoreResources)
dependsOn(copyCommonResources)
dependsOn(copyAccessWidener)
jvmArgs "-XX:-OmitStackTraceInFastThrow"
finalizedBy(deleteResources)
}
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 {
manifest {
attributes 'Implementation-Title': rootProject.archives_base_name,
'Implementation-Version': rootProject.mod_version,
'Main-Class': 'com.seibel.lod.core.JarMain' // When changing the main of the jar change this line
}
classifier "dev"
}
sourcesJar {
def commonSources = project(":common").sourcesJar
dependsOn commonSources
from commonSources.archiveFile.map { zipTree(it) }
}
components.java {
withVariantsFromConfiguration(project.configurations.shadowRuntimeElements) {
skip()
}
}
publishing {
publications {
mavenFabric(MavenPublication) {
artifactId = rootProject.archives_base_name + "-" + project.name
from components.java
}
}
// See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing.
repositories {
// Add repositories to publish to here.
}
}
task printConfigurations {
doLast {task ->
println "Project Name: $name configurations:"
configurations.each {
println " $it.name"
}
}
}
tasks.withType(JavaCompile) {
// Add Manifold Preprocessor
// def excapedMCVersion = rootProject.minecraft_version.replace(".", "_")
// options.compilerArgs += ['-Xplugin:Manifold', "-AMC_VERSION_${excapedMCVersion}"]
//
//options.compilerArgs += ['-deprecation']
//options.compilerArgs += ['-verbose']
//options.compilerArgs += ['-Xlint:unchecked']
//options.compilerArgs += ['-Xdiags:verbose']
//options.compilerArgs += ['-Xprint']
//options.compilerArgs += ['-XprintProcessorInfo']
//options.compilerArgs += ['-XprintRounds']
// println options.compilerArgs
// Set the java version
options.compilerArgs += ['-Xplugin:Manifold']
options.release = rootProject.java_version as Integer
// TODO: make everything use java 8
// options.release = 8 // Use Java 8 for everything so back porting is easier
}
@@ -1,199 +0,0 @@
/*
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
* licensed under the GNU GPL 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 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.ClientChunkEvents;
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.client.gui.screens.TitleScreen;
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 coolGi
* @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);
#if PRE_MC_1_18_1 // in 1.18+, we use mixin hook in setClientLightReady(true)
ClientChunkEvents.CHUNK_LOAD.register(this::chunkLoadEvent);
#endif
/* 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 (Minecraft.getInstance().screen instanceof TitleScreen) return;
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 int[] KEY_TO_CHECK_FOR = {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 = GLFW.GLFW_KEY_A; i <= GLFW.GLFW_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,95 +0,0 @@
/*
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
* licensed under the GNU GPL 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 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.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 coolGi
* @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);
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);
FabricDependencySetup.createInitialBindings();
FabricDependencySetup.finishBinding();
ApiShared.LOGGER.info(ModInfo.READABLE_NAME + ", Version: " + ModInfo.VERSION);
}
}
@@ -1,55 +0,0 @@
/*
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
* licensed under the GNU GPL 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 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.mixins;
import org.spongepowered.asm.mixin.Mixin;
import net.minecraft.world.level.chunk.ChunkGenerator;
#if PRE_MC_1_18_1
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
import net.minecraft.core.BlockPos;
import net.minecraft.server.level.WorldGenRegion;
import net.minecraft.world.level.StructureFeatureManager;
import net.minecraft.world.level.biome.Biome;
import net.minecraft.world.level.levelgen.WorldgenRandom;
@Mixin(ChunkGenerator.class)
public class MixinChunkGenerator {
@Redirect(method = "applyBiomeDecoration", at = @At(
value = "INVOKE",
target = "Lnet/minecraft/world/level/biome/Biome;generate(Lnet/minecraft/world/level/StructureFeatureManager;"
+ "Lnet/minecraft/world/level/chunk/ChunkGenerator;Lnet/minecraft/server/level/WorldGenRegion;J"
+ "Lnet/minecraft/world/level/levelgen/WorldgenRandom;Lnet/minecraft/core/BlockPos;)V"
))
private void wrapBiomeGenerateCall(Biome biome, StructureFeatureManager structFeatManager, ChunkGenerator generator,
WorldGenRegion genRegion, long l, WorldgenRandom random, BlockPos pos) {
synchronized(ChunkGenerator.class) {
biome.generate(structFeatManager, (ChunkGenerator)(Object)this, genRegion, l, random, pos);
}
}
}
#else
@Mixin(ChunkGenerator.class)
public class MixinChunkGenerator {}
#endif
@@ -1,24 +0,0 @@
package com.seibel.lod.fabric.mixins;
import com.seibel.lod.core.render.F3Screen;
import net.minecraft.client.gui.components.DebugScreenOverlay;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import java.util.List;
@Mixin(DebugScreenOverlay.class)
public class MixinDebugScreenOverlay {
@Inject(method = "getSystemInformation", at = @At("RETURN"))
private void addCustomF3(CallbackInfoReturnable<List<String>> cir) {
List<String> messages = cir.getReturnValue();
for (String i: F3Screen.f3List) {
messages.add(i);
}
}
}
@@ -1,35 +0,0 @@
/*
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
* licensed under the GNU GPL 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 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.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,80 +0,0 @@
/*
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
* licensed under the GNU GPL 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 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.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;
#if PRE_MC_1_17_1
import net.minecraft.world.level.material.FluidState;
#else
import net.minecraft.world.level.material.FogType;
#endif
@Mixin(FogRenderer.class)
public class MixinFogRenderer {
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")
#if PRE_MC_1_19_1
private static void disableSetupFog(Camera camera, FogMode fogMode, float f, boolean bl, CallbackInfo callback) {
#else
private static void disableSetupFog(Camera camera, FogMode fogMode, float f, boolean bl, float g, CallbackInfo callback) {
#endif
#if PRE_MC_1_17_1
FluidState fluidState = camera.getFluidInCamera();
boolean cameraNotInFluid = fluidState.isEmpty();
#else
FogType fogTypes = camera.getFluidInCamera();
boolean cameraNotInFluid = fogTypes == FogType.NONE;
#endif
Entity entity = camera.getEntity();
boolean isSpecialFog = (entity instanceof LivingEntity) && ((LivingEntity) entity).hasEffect(MobEffects.BLINDNESS);
if (!isSpecialFog && cameraNotInFluid && fogMode == FogMode.FOG_TERRAIN
&& CONFIG.client().graphics().fogQuality().getDisableVanillaFog())
{
#if PRE_MC_1_17_1
RenderSystem.fogStart(A_REALLY_REALLY_BIG_VALUE);
RenderSystem.fogEnd(A_EVEN_LARGER_VALUE);
#else
RenderSystem.setShaderFogStart(A_REALLY_REALLY_BIG_VALUE);
RenderSystem.setShaderFogEnd(A_EVEN_LARGER_VALUE);
#endif
}
}
}
@@ -1,40 +0,0 @@
/*
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
* licensed under the GNU GPL 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 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.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,78 +0,0 @@
/*
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
* licensed under the GNU GPL 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 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.mixins;
import com.seibel.lod.common.wrappers.config.ConfigGui;
import com.seibel.lod.common.wrappers.config.TexturedButtonWidget;
import com.seibel.lod.core.ModInfo;
import com.seibel.lod.core.handlers.dependencyInjection.SingletonHandler;
import com.seibel.lod.core.wrapperInterfaces.config.ILodConfigWrapperSingleton;
import net.minecraft.client.gui.screens.OptionsScreen;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.network.chat.Component;
#if PRE_MC_1_19_1
import net.minecraft.network.chat.TranslatableComponent;
#endif
import net.minecraft.resources.ResourceLocation;
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 java.util.Objects;
/**
* Adds a button to the menu to goto the config
*
* @author coolGi
* @version 12-02-2021
*/
@Mixin(OptionsScreen.class)
public class MixinOptionsScreen extends Screen {
// Get the texture for the button
private static final ResourceLocation ICON_TEXTURE = new ResourceLocation(ModInfo.ID,"textures/gui/button.png");
protected MixinOptionsScreen(Component title) {
super(title);
}
@Inject(at = @At("HEAD"),method = "init")
private void lodconfig$init(CallbackInfo ci) {
if (SingletonHandler.get(ILodConfigWrapperSingleton.class).client().getOptionsButton())
this. #if PRE_MC_1_17_1 addButton #else addRenderableWidget #endif
(new TexturedButtonWidget(
// Where the button is on the screen
this.width / 2 - 180, this.height / 6 - 12,
// Width and height of the button
20, 20,
// Offset
0, 0,
// Some textuary stuff
20, ICON_TEXTURE, 20, 40,
// Create the button and tell it where to go
// For now it goes to the client option by default
(buttonWidget) -> Objects.requireNonNull(minecraft).setScreen(ConfigGui.getScreen(this, "client")),
// Add a title to the screen
#if PRE_MC_1_19_1
new TranslatableComponent("text.autoconfig." + ModInfo.ID + ".title")));
#else
Component.translatable("text.autoconfig." + ModInfo.ID + ".title")));
#endif
}
}
@@ -1,73 +0,0 @@
/*
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
* licensed under the GNU GPL 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 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.mixins;
import java.util.concurrent.ExecutorService;
import java.util.function.Supplier;
import com.seibel.lod.fabric.ClientProxy;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import com.seibel.lod.core.util.DummyRunExecutorService;
import net.minecraft.Util;
@Mixin(Util.class)
public class MixinUtilBackgroudThread
{
@Inject(method = "backgroundExecutor", at = @At("HEAD"), cancellable = true)
private static void overrideUtil$backgroundExecutor(CallbackInfoReturnable<ExecutorService> ci)
{
if (ClientProxy.isGenerationThreadChecker != null && ClientProxy.isGenerationThreadChecker.get())
{
//ApiShared.LOGGER.info("util backgroundExecutor triggered");
ci.setReturnValue(new DummyRunExecutorService());
}
}
#if POST_MC_1_17_1
@Inject(method = "wrapThreadWithTaskName(Ljava/lang/String;Ljava/lang/Runnable;)Ljava/lang/Runnable;",
at = @At("HEAD"), cancellable = true)
private static void overrideUtil$wrapThreadWithTaskName(String string, Runnable r, CallbackInfoReturnable<Runnable> ci)
{
if (ClientProxy.isGenerationThreadChecker != null && ClientProxy.isGenerationThreadChecker.get())
{
//ApiShared.LOGGER.info("util wrapThreadWithTaskName(Runnable) triggered");
ci.setReturnValue(r);
}
}
#endif
#if POST_MC_1_18_1
@Inject(method = "wrapThreadWithTaskName(Ljava/lang/String;Ljava/util/function/Supplier;)Ljava/util/function/Supplier;",
at = @At("HEAD"), cancellable = true)
private static void overrideUtil$wrapThreadWithTaskNameForSupplier(String string, Supplier<?> r, CallbackInfoReturnable<Supplier<?>> ci)
{
if (ClientProxy.isGenerationThreadChecker != null && ClientProxy.isGenerationThreadChecker.get())
{
//ApiShared.LOGGER.info("util wrapThreadWithTaskName(Supplier) triggered");
ci.setReturnValue(r);
}
}
#endif
}
@@ -1,118 +0,0 @@
/*
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
* licensed under the GNU GPL 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 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.mixins;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.math.Matrix4f;
import com.seibel.lod.common.Config;
import com.seibel.lod.common.wrappers.McObjectConverter;
import com.seibel.lod.core.api.ClientApi;
import com.seibel.lod.core.objects.math.Mat4f;
import net.minecraft.client.Camera;
import net.minecraft.client.renderer.LevelRenderer;
import net.minecraft.client.renderer.RenderType;
import org.lwjgl.opengl.GL15;
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;
/**
* This class is used to mix in my rendering code
* before Minecraft starts rendering blocks.
* If this wasn't done, and we used Forge's
* render last event, the LODs would render on top
* of the normal terrain.
*
* This is also the mixin for rendering the clouds
*
* @author coolGi
* @author James Seibel
* @version 12-31-2021
*/
@Mixin(LevelRenderer.class)
public class MixinWorldRenderer
{
private static float previousPartialTicks = 0;
public MixinWorldRenderer() {
throw new NullPointerException("Null cannot be cast to non-null type.");
}
// Inject rendering at first call to renderChunkLayer
// HEAD or RETURN
#if PRE_MC_1_17_1
@Inject(at = @At("RETURN"), method = "renderSky(Lcom/mojang/blaze3d/vertex/PoseStack;F)V")
private void renderSky(PoseStack matrixStackIn, float partialTicks, CallbackInfo callback)
{
// get the partial ticks since renderBlockLayer doesn't
// have access to them
previousPartialTicks = partialTicks;
}
@Inject(at = @At("HEAD"),
method = "renderChunkLayer(Lnet/minecraft/client/renderer/RenderType;Lcom/mojang/blaze3d/vertex/PoseStack;DDD)V",
cancellable = true)
private void renderChunkLayer(RenderType renderType, PoseStack matrixStackIn, double xIn, double yIn, double zIn, CallbackInfo callback)
{
// only render before solid blocks
if (renderType.equals(RenderType.solid()))
{
// get MC's current projection matrix
float[] mcProjMatrixRaw = new float[16];
GL15.glGetFloatv(GL15.GL_PROJECTION_MATRIX, mcProjMatrixRaw);
Mat4f mcProjectionMatrix = new Mat4f(mcProjMatrixRaw);
mcProjectionMatrix.transpose();
Mat4f mcModelViewMatrix = McObjectConverter.Convert(matrixStackIn.last().pose());
ClientApi.INSTANCE.renderLods(mcModelViewMatrix, mcProjectionMatrix, previousPartialTicks);
}
if (Config.Client.Advanced.lodOnlyMode) {
callback.cancel();
}
}
#else
@Inject(method = "renderClouds", at = @At("HEAD"), cancellable = true)
public void renderClouds(PoseStack poseStack, Matrix4f projectionMatrix, float tickDelta, double cameraX, double cameraY, double cameraZ, CallbackInfo ci) {
// get the partial ticks since renderChunkLayer doesn't
// have access to them
previousPartialTicks = tickDelta;
}
@Inject(at = @At("HEAD"),
method = "renderChunkLayer(Lnet/minecraft/client/renderer/RenderType;Lcom/mojang/blaze3d/vertex/PoseStack;DDDLcom/mojang/math/Matrix4f;)V",
cancellable = true)
private void renderChunkLayer(RenderType renderType, PoseStack modelViewMatrixStack, double cameraXBlockPos, double cameraYBlockPos, double cameraZBlockPos, Matrix4f projectionMatrix, CallbackInfo callback)
{
// only render before solid blocks
if (renderType.equals(RenderType.solid()))
{
Mat4f mcModelViewMatrix = McObjectConverter.Convert(modelViewMatrixStack.last().pose());
Mat4f mcProjectionMatrix = McObjectConverter.Convert(projectionMatrix);
ClientApi.INSTANCE.renderLods(mcModelViewMatrix, mcProjectionMatrix, previousPartialTicks);
}
if (Config.Client.Advanced.lodOnlyMode) {
callback.cancel();
}
}
#endif
}
@@ -1,46 +0,0 @@
/*
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
* licensed under the GNU GPL 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 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.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());
}
}
@@ -1,66 +0,0 @@
/*
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
* licensed under the GNU GPL 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 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.mixins.events;
import com.seibel.lod.fabric.Main;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.client.multiplayer.ClientPacketListener;
import net.minecraft.client.renderer.LevelRenderer;
#if POST_MC_1_18_2
import net.minecraft.core.Holder;
#endif
import net.minecraft.resources.ResourceKey;
import net.minecraft.util.profiling.ProfilerFiller;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.chunk.LevelChunk;
import net.minecraft.world.level.dimension.DimensionType;
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 java.util.function.Supplier;
/**
* This class is used for world loading events
* @author Ran
*
* FIXME: Why does forge not have the 1.18+ onChunkLightReady mixin?
*/
@Mixin(ClientLevel.class)
public class MixinClientLevel {
@Inject(method = "<init>", at = @At("TAIL"))
private void loadWorldEvent(ClientPacketListener clientPacketListener, ClientLevel.ClientLevelData clientLevelData, ResourceKey resourceKey,
#if POST_MC_1_18_2 Holder holder, #else DimensionType dimensionType, #endif int i,
#if POST_MC_1_18_1 int j, #endif Supplier supplier, LevelRenderer levelRenderer, boolean bl, long l, CallbackInfo ci) {
Main.client_proxy.worldLoadEvent((ClientLevel) (Object) this);
}
#if POST_MC_1_18_1
@Inject(method = "setLightReady", at = @At("HEAD"))
private void onChunkLightReady(int x, int z, CallbackInfo ci) {
ClientLevel l = (ClientLevel) (Object) this;
LevelChunk chunk = l.getChunkSource().getChunk(x, z, false);
if (chunk!=null&& !chunk.isClientLightReady())
Main.client_proxy.chunkLoadEvent(l, chunk);
}
#endif
}
@@ -1,28 +0,0 @@
package com.seibel.lod.fabric.mixins.events;
import com.mojang.blaze3d.platform.NativeImage;
import com.seibel.lod.common.wrappers.minecraft.MinecraftRenderWrapper;
import com.seibel.lod.core.api.ApiShared;
import net.minecraft.client.renderer.LightTexture;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(LightTexture.class)
public class MixinLightmap {
@Shadow
@Final
public NativeImage lightPixels;
@Inject(method="updateLightTexture", at=@At(
value="INVOKE",
target="Lnet/minecraft/client/renderer/texture/DynamicTexture;upload()V"))
public void updateLightTexture(float f, CallbackInfo ci) {
//ApiShared.LOGGER.info("Lightmap update");
MinecraftRenderWrapper.INSTANCE.updateLightmap(lightPixels);
}
}
@@ -1,51 +0,0 @@
/*
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
* licensed under the GNU GPL 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 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.mixins.events;
import com.seibel.lod.fabric.Main;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.client.multiplayer.ClientLevel;
import org.jetbrains.annotations.Nullable;
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;
/**
* This class is used for world unloading events
* @author Ran
*/
@Mixin(Minecraft.class)
public class MixinMinecraft {
@Shadow @Nullable public ClientLevel level;
@Inject(method = "setLevel", at = @At("HEAD"))
private void unloadWorldEvent_sL(ClientLevel clientLevel, CallbackInfo ci) {
if (level != null) Main.client_proxy.worldUnloadEvent(level);
}
@Inject(method = "clearLevel(Lnet/minecraft/client/gui/screens/Screen;)V", at = @At("HEAD"))
private void unloadWorldEvent_cL(Screen screen, CallbackInfo ci) {
if (this.level != null) Main.client_proxy.worldUnloadEvent(this.level);
}
}
@@ -1,51 +0,0 @@
/*
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
* licensed under the GNU GPL 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 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.mixins.events;
import com.seibel.lod.fabric.Main;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.util.ProgressListener;
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;
/**
* This class is used for world saving events
* @author Ran
*/
@Mixin(ServerLevel.class)
public class MixinServerLevel {
#if PRE_MC_1_17_1
@Inject(method = "save", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ServerChunkCache;save(Z)V", shift = At.Shift.AFTER))
private void saveWorldEvent(ProgressListener progressListener, boolean bl, boolean bl2, CallbackInfo ci) {
Main.client_proxy.worldSaveEvent();
}
#else
@Inject(method = "save", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/entity/PersistentEntitySectionManager;saveAll()V", shift = At.Shift.AFTER))
private void saveWorldEvent_sA(ProgressListener progressListener, boolean bl, boolean bl2, CallbackInfo ci) {
Main.client_proxy.worldSaveEvent();
}
@Inject(method = "save", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/entity/PersistentEntitySectionManager;autoSave()V", shift = At.Shift.AFTER))
private void saveWorldEvent_aS(ProgressListener progressListener, boolean bl, boolean bl2, CallbackInfo ci) {
Main.client_proxy.worldSaveEvent();
}
#endif
}
@@ -1,53 +0,0 @@
/*
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
* licensed under the GNU GPL 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 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.mixins.unsafe;
import net.minecraft.server.level.ServerLevel;
import org.spongepowered.asm.mixin.Mixin;
#if POST_MC_1_18_1
import net.minecraft.util.ThreadingDetector;
import org.spongepowered.asm.mixin.Mutable;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import java.util.concurrent.Semaphore;
/**
* Why does this exist? But okay! (Will be probably removed when the experimental generator is done)
*/
@Mixin(ThreadingDetector.class)
public class MixinThreadingDectector {
@Mutable
@Shadow
private Semaphore lock;
@Inject(method = "<init>", at = @At("RETURN"))
private void setSemaphore(CallbackInfo ci) {
this.lock = new Semaphore(2);
}
}
#else
@Mixin(ServerLevel.class)
public class MixinThreadingDectector {} //FIXME: Is there some way to make this file just not be added?
#endif
@@ -1,50 +0,0 @@
/*
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
* licensed under the GNU GPL 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 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.wrappers;
import com.seibel.lod.core.handlers.dependencyInjection.SingletonHandler;
import com.seibel.lod.core.wrapperInterfaces.config.ILodConfigWrapperSingleton;
import com.seibel.lod.common.wrappers.config.LodConfigWrapperSingleton;
import com.seibel.lod.core.wrapperInterfaces.modAccessor.IModChecker;
import com.seibel.lod.fabric.wrappers.modAccessor.ModChecker;
/**
* Binds all necessary dependencies, so we
* can access them in Core. <br>
* This needs to be called before any Core classes
* are loaded.
*
* @author James Seibel
* @author Ran
* @version 3-5-2022
*/
public class FabricDependencySetup
{
public static void createInitialBindings()
{
SingletonHandler.bind(IModChecker.class, ModChecker.INSTANCE);
SingletonHandler.bind(ILodConfigWrapperSingleton.class, LodConfigWrapperSingleton.INSTANCE);
}
public static void finishBinding() {
SingletonHandler.finishBinding();
}
}
@@ -1,38 +0,0 @@
/*
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
* licensed under the GNU GPL 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 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.wrappers.config;
import com.seibel.lod.common.wrappers.config.ConfigGui;
import com.terraformersmc.modmenu.api.ConfigScreenFactory;
import com.terraformersmc.modmenu.api.ModMenuApi;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
/**
* For making the config show up in modmenu
*/
@Environment(EnvType.CLIENT)
public class ModMenuIntegration implements ModMenuApi {
// For the custom config code
@Override
public ConfigScreenFactory<?> getModConfigScreenFactory() {
return parent -> ConfigGui.getScreen(parent, "");
}
}
@@ -1,117 +0,0 @@
/*
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
* licensed under the GNU GPL 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 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.wrappers.modAccessor;
import java.util.HashSet;
import java.util.stream.Collectors;
import com.seibel.lod.core.handlers.dependencyInjection.SingletonHandler;
import com.seibel.lod.core.wrapperInterfaces.IWrapperFactory;
import com.seibel.lod.core.wrapperInterfaces.chunk.AbstractChunkPosWrapper;
import com.seibel.lod.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
import com.seibel.lod.core.wrapperInterfaces.modAccessor.ISodiumAccessor;
import me.jellysquid.mods.sodium.client.render.SodiumWorldRenderer;
import net.minecraft.client.Minecraft;
#if PRE_MC_1_17_1
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.protocol.Packet;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.level.LevelAccessor;
import net.minecraft.world.phys.AABB;
#else
import net.minecraft.world.level.LevelHeightAccessor;
#endif
public class SodiumAccessor implements ISodiumAccessor {
private final IWrapperFactory factory = SingletonHandler.get(IWrapperFactory.class);
private final IMinecraftRenderWrapper MC_RENDER = SingletonHandler.get(IMinecraftRenderWrapper.class);
@Override
public String getModName() {
return "Sodium-Fabric";
}
#if POST_MC_1_17_1
@Override
public HashSet<AbstractChunkPosWrapper> getNormalRenderedChunks() {
SodiumWorldRenderer renderer = SodiumWorldRenderer.instance();
LevelHeightAccessor height = Minecraft.getInstance().level;
#if POST_MC_1_18_1
// 0b11 = Lighted chunk & loaded chunk
return renderer.getChunkTracker().getChunks(0b00).filter(
(long l) -> {
return true;
}).mapToObj((long l) -> {
return (AbstractChunkPosWrapper)factory.createChunkPos(l);
}).collect(Collectors.toCollection(HashSet::new));
#else
// TODO: Maybe use a mixin to make this more efficient, and maybe ignore changes behind the camera
return MC_RENDER.getMaximumRenderedChunks().stream().filter((AbstractChunkPosWrapper chunk) -> {
return (renderer.isBoxVisible(
chunk.getMinBlockX()+1, height.getMinBuildHeight()+1, chunk.getMinBlockZ()+1,
chunk.getMinBlockX()+15, height.getMaxBuildHeight()-1, chunk.getMinBlockZ()+15));
}).collect(Collectors.toCollection(HashSet::new));
#endif
}
#else
@Override
public HashSet<AbstractChunkPosWrapper> getNormalRenderedChunks() {
SodiumWorldRenderer renderer = SodiumWorldRenderer.getInstance();
LevelAccessor height = Minecraft.getInstance().level;
// TODO: Maybe use a mixin to make this more efficient
return MC_RENDER.getMaximumRenderedChunks().stream().filter((AbstractChunkPosWrapper chunk) -> {
FakeChunkEntity AABB = new FakeChunkEntity(chunk.getX(), chunk.getZ(), height.getMaxBuildHeight());
return (renderer.isEntityVisible(AABB));
}).collect(Collectors.toCollection(HashSet::new));
}
private static class FakeChunkEntity extends Entity {
public int cx;
public int cz;
public int my;
public FakeChunkEntity(int chunkX, int chunkZ, int maxHeight) {
super(EntityType.AREA_EFFECT_CLOUD, null);
cx = chunkX;
cz = chunkZ;
my = maxHeight;
}
@Override
public AABB getBoundingBoxForCulling() {
return new AABB(cx*16+1, 1, cz*16+1,
cx*16+15, my-1, cz*16+15);
}
@Override
protected void defineSynchedData() {}
@Override
protected void readAdditionalSaveData(CompoundTag paramCompoundTag) {}
@Override
protected void addAdditionalSaveData(CompoundTag paramCompoundTag) {}
@Override
public Packet<?> getAddEntityPacket() {
throw new UnsupportedOperationException("This is a FAKE CHUNK ENTITY... For tricking the Sodium to check a AABB.");
}
}
#endif
}
@@ -1,458 +0,0 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 2.1, February 1999
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
[This is the first released version of the Lesser GPL. It also counts
as the successor of the GNU Library Public License, version 2, hence
the version number 2.1.]
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
Licenses are intended to guarantee your freedom to share and change
free software--to make sure the software is free for all its users.
This license, the Lesser General Public License, applies to some
specially designated software packages--typically libraries--of the
Free Software Foundation and other authors who decide to use it. You
can use it too, but we suggest you first think carefully about whether
this license or the ordinary General Public License is the better
strategy to use in any particular case, based on the explanations below.
When we speak of free software, we are referring to freedom of use,
not price. Our General Public Licenses are designed to make sure that
you have the freedom to distribute copies of free software (and charge
for this service if you wish); that you receive source code or can get
it if you want it; that you can change the software and use pieces of
it in new free programs; and that you are informed that you can do
these things.
To protect your rights, we need to make restrictions that forbid
distributors to deny you these rights or to ask you to surrender these
rights. These restrictions translate to certain responsibilities for
you if you distribute copies of the library or if you modify it.
For example, if you distribute copies of the library, whether gratis
or for a fee, you must give the recipients all the rights that we gave
you. You must make sure that they, too, receive or can get the source
code. If you link other code with the library, you must provide
complete object files to the recipients, so that they can relink them
with the library after making changes to the library and recompiling
it. And you must show them these terms so they know their rights.
We protect your rights with a two-step method: (1) we copyright the
library, and (2) we offer you this license, which gives you legal
permission to copy, distribute and/or modify the library.
To protect each distributor, we want to make it very clear that
there is no warranty for the free library. Also, if the library is
modified by someone else and passed on, the recipients should know
that what they have is not the original version, so that the original
author's reputation will not be affected by problems that might be
introduced by others.
Finally, software patents pose a constant threat to the existence of
any free program. We wish to make sure that a company cannot
effectively restrict the users of a free program by obtaining a
restrictive license from a patent holder. Therefore, we insist that
any patent license obtained for a version of the library must be
consistent with the full freedom of use specified in this license.
Most GNU software, including some libraries, is covered by the
ordinary GNU General Public License. This license, the GNU Lesser
General Public License, applies to certain designated libraries, and
is quite different from the ordinary General Public License. We use
this license for certain libraries in order to permit linking those
libraries into non-free programs.
When a program is linked with a library, whether statically or using
a shared library, the combination of the two is legally speaking a
combined work, a derivative of the original library. The ordinary
General Public License therefore permits such linking only if the
entire combination fits its criteria of freedom. The Lesser General
Public License permits more lax criteria for linking other code with
the library.
We call this license the "Lesser" General Public License because it
does Less to protect the user's freedom than the ordinary General
Public License. It also provides other free software developers Less
of an advantage over competing non-free programs. These disadvantages
are the reason we use the ordinary General Public License for many
libraries. However, the Lesser license provides advantages in certain
special circumstances.
For example, on rare occasions, there may be a special need to
encourage the widest possible use of a certain library, so that it becomes
a de-facto standard. To achieve this, non-free programs must be
allowed to use the library. A more frequent case is that a free
library does the same job as widely used non-free libraries. In this
case, there is little to gain by limiting the free library to free
software only, so we use the Lesser General Public License.
In other cases, permission to use a particular library in non-free
programs enables a greater number of people to use a large body of
free software. For example, permission to use the GNU C Library in
non-free programs enables many more people to use the whole GNU
operating system, as well as its variant, the GNU/Linux operating
system.
Although the Lesser General Public License is Less protective of the
users' freedom, it does ensure that the user of a program that is
linked with the Library has the freedom and the wherewithal to run
that program using a modified version of the Library.
The precise terms and conditions for copying, distribution and
modification follow. Pay close attention to the difference between a
"work based on the library" and a "work that uses the library". The
former contains code derived from the library, whereas the latter must
be combined with the library in order to run.
GNU LESSER GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any software library or other
program which contains a notice placed by the copyright holder or
other authorized party saying it may be distributed under the terms of
this Lesser General Public License (also called "this License").
Each licensee is addressed as "you".
A "library" means a collection of software functions and/or data
prepared so as to be conveniently linked with application programs
(which use some of those functions and data) to form executables.
The "Library", below, refers to any such software library or work
which has been distributed under these terms. A "work based on the
Library" means either the Library or any derivative work under
copyright law: that is to say, a work containing the Library or a
portion of it, either verbatim or with modifications and/or translated
straightforwardly into another language. (Hereinafter, translation is
included without limitation in the term "modification".)
"Source code" for a work means the preferred form of the work for
making modifications to it. For a library, complete source code means
all the source code for all modules it contains, plus any associated
interface definition files, plus the scripts used to control compilation
and installation of the library.
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running a program using the Library is not restricted, and output from
such a program is covered only if its contents constitute a work based
on the Library (independent of the use of the Library in a tool for
writing it). Whether that is true depends on what the Library does
and what the program that uses the Library does.
1. You may copy and distribute verbatim copies of the Library's
complete source code as you receive it, in any medium, provided that
you conspicuously and appropriately publish on each copy an
appropriate copyright notice and disclaimer of warranty; keep intact
all the notices that refer to this License and to the absence of any
warranty; and distribute a copy of this License along with the
Library.
You may charge a fee for the physical act of transferring a copy,
and you may at your option offer warranty protection in exchange for a
fee.
2. You may modify your copy or copies of the Library or any portion
of it, thus forming a work based on the Library, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) The modified work must itself be a software library.
b) You must cause the files modified to carry prominent notices
stating that you changed the files and the date of any change.
c) You must cause the whole of the work to be licensed at no
charge to all third parties under the terms of this License.
d) If a facility in the modified Library refers to a function or a
table of data to be supplied by an application program that uses
the facility, other than as an argument passed when the facility
is invoked, then you must make a good faith effort to ensure that,
in the event an application does not supply such function or
table, the facility still operates, and performs whatever part of
its purpose remains meaningful.
(For example, a function in a library to compute square roots has
a purpose that is entirely well-defined independent of the
application. Therefore, Subsection 2d requires that any
application-supplied function or table used by this function must
be optional: if the application does not supply it, the square
root function must still compute square roots.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Library,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Library, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote
it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Library.
In addition, mere aggregation of another work not based on the Library
with the Library (or with a work based on the Library) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may opt to apply the terms of the ordinary GNU General Public
License instead of this License to a given copy of the Library. To do
this, you must alter all the notices that refer to this License, so
that they refer to the ordinary GNU General Public License, version 2,
instead of to this License. (If a newer version than version 2 of the
ordinary GNU General Public License has appeared, then you can specify
that version instead if you wish.) Do not make any other change in
these notices.
Once this change is made in a given copy, it is irreversible for
that copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy.
This option is useful when you wish to copy part of the code of
the Library into a program that is not a library.
4. You may copy and distribute the Library (or a portion or
derivative of it, under Section 2) in object code or executable form
under the terms of Sections 1 and 2 above provided that you accompany
it with the complete corresponding machine-readable source code, which
must be distributed under the terms of Sections 1 and 2 above on a
medium customarily used for software interchange.
If distribution of object code is made by offering access to copy
from a designated place, then offering equivalent access to copy the
source code from the same place satisfies the requirement to
distribute the source code, even though third parties are not
compelled to copy the source along with the object code.
5. A program that contains no derivative of any portion of the
Library, but is designed to work with the Library by being compiled or
linked with it, is called a "work that uses the Library". Such a
work, in isolation, is not a derivative work of the Library, and
therefore falls outside the scope of this License.
However, linking a "work that uses the Library" with the Library
creates an executable that is a derivative of the Library (because it
contains portions of the Library), rather than a "work that uses the
library". The executable is therefore covered by this License.
Section 6 states terms for distribution of such executables.
When a "work that uses the Library" uses material from a header file
that is part of the Library, the object code for the work may be a
derivative work of the Library even though the source code is not.
Whether this is true is especially significant if the work can be
linked without the Library, or if the work is itself a library. The
threshold for this to be true is not precisely defined by law.
If such an object file uses only numerical parameters, data
structure layouts and accessors, and small macros and small inline
functions (ten lines or less in length), then the use of the object
file is unrestricted, regardless of whether it is legally a derivative
work. (Executables containing this object code plus portions of the
Library will still fall under Section 6.)
Otherwise, if the work is a derivative of the Library, you may
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.
6. As an exception to the Sections above, you may also combine or
link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work
under terms of your choice, provided that the terms permit
modification of the work for the customer's own use and reverse
engineering for debugging such modifications.
You must give prominent notice with each copy of the work that the
Library is used in it and that the Library and its use are covered by
this License. You must supply a copy of this License. If the work
during execution displays copyright notices, you must include the
copyright notice for the Library among them, as well as a reference
directing the user to the copy of this License. Also, you must do one
of these things:
a) Accompany the work with the complete corresponding
machine-readable source code for the Library including whatever
changes were used in the work (which must be distributed under
Sections 1 and 2 above); and, if the work is an executable linked
with the Library, with the complete machine-readable "work that
uses the Library", as object code and/or source code, so that the
user can modify the Library and then relink to produce a modified
executable containing the modified Library. (It is understood
that the user who changes the contents of definitions files in the
Library will not necessarily be able to recompile the application
to use the modified definitions.)
b) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (1) uses at run time a
copy of the library already present on the user's computer system,
rather than copying library functions into the executable, and (2)
will operate properly with a modified version of the library, if
the user installs one, as long as the modified version is
interface-compatible with the version that the work was made with.
c) Accompany the work with a written offer, valid for at
least three years, to give the same user the materials
specified in Subsection 6a, above, for a charge no more
than the cost of performing this distribution.
d) If distribution of the work is made by offering access to copy
from a designated place, offer equivalent access to copy the above
specified materials from the same place.
e) Verify that the user has already received a copy of these
materials or that you have already sent this user a copy.
For an executable, the required form of the "work that uses the
Library" must include any data and utility programs needed for
reproducing the executable from it. However, as a special exception,
the materials to be distributed need not include anything that is
normally distributed (in either source or binary form) with the major
components (compiler, kernel, and so on) of the operating system on
which the executable runs, unless that component itself accompanies
the executable.
It may happen that this requirement contradicts the license
restrictions of other proprietary libraries that do not normally
accompany the operating system. Such a contradiction means you cannot
use both them and the Library together in an executable that you
distribute.
7. 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 not covered by this License, and distribute such a combined
library, provided that the separate distribution of the work based on
the Library and of the other library facilities is otherwise
permitted, and provided that you do these two things:
a) Accompany the combined library with a copy of the same work
based on the Library, uncombined with any other library
facilities. This must be distributed under the terms of the
Sections above.
b) Give prominent notice with the combined library of the fact
that part of it is a work based on the Library, and explaining
where to find the accompanying uncombined form of the same work.
8. You may not copy, modify, sublicense, link with, or distribute
the Library except as expressly provided under this License. Any
attempt otherwise to copy, modify, sublicense, link with, or
distribute the Library is void, and will automatically terminate your
rights under this License. However, parties who have received copies,
or rights, from you under this License will not have their licenses
terminated so long as such parties remain in full compliance.
9. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Library or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Library (or any work based on the
Library), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Library or works based on it.
10. Each time you redistribute the Library (or any work based on the
Library), the recipient automatically receives a license from the
original licensor to copy, distribute, link with or modify the Library
subject to these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties with
this License.
11. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Library at all. For example, if a patent
license would not permit royalty-free redistribution of the Library by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Library.
If any portion of this section is held invalid or unenforceable under any
particular circumstance, the balance of the section is intended to apply,
and the section as a whole is intended to apply in other circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
12. If the distribution and/or use of the Library is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Library under this License may add
an explicit geographical distribution limitation excluding those countries,
so that distribution is permitted only in or among countries not thus
excluded. In such case, this License incorporates the limitation as if
written in the body of this License.
13. The Free Software Foundation may publish revised and/or new
versions of the 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
specifies a version number of this License which applies to it and
"any later version", you have the option of following the terms and
conditions either of that version or of any later version published by
the Free Software Foundation. If the Library does not specify a
license version number, you may choose any version ever published by
the Free Software Foundation.
14. If you wish to incorporate parts of the Library into other free
programs whose distribution conditions are incompatible with these,
write to the author to ask for permission. For software which is
copyrighted by the Free Software Foundation, write to the Free
Software Foundation; we sometimes make exceptions for this. Our
decision will be guided by the two goals of preserving the free status
of all derivatives of our free software and of promoting the sharing
and reuse of software generally.
NO WARRANTY
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.
END OF TERMS AND CONDITIONS
@@ -1,28 +0,0 @@
{
"required": true,
"minVersion": "0.8",
"package": "com.seibel.lod.fabric.mixins",
"mixins": [
"unsafe.MixinThreadingDectector",
"MixinUtilBackgroudThread",
"events.MixinServerLevel"
],
"client": [
"MixinMinecraft",
"MixinOptionsScreen",
"MixinWorldRenderer",
"MixinFogRenderer",
"MixinChunkGenerator",
"MixinDebugScreenOverlay",
"events.MixinClientLevel",
"events.MixinMinecraft",
"events.MixinBlockUpdate",
"events.MixinLightmap"
],
"server": [
"MixinDedicatedServer"
],
"injectors": {
"defaultRequire": 1
}
}
-50
View File
@@ -1,50 +0,0 @@
{
"schemaVersion": 1,
"id": "lod",
"version": "${version}",
"name": "${mod_name}",
"description": "${description}",
"authors": $authors,
"contact": {
"homepage": "${homepage}",
"sources": "${source}",
"issues": "${issues}"
},
"license": "CC0-1.0",
"icon": "icon.png",
"environment": "client",
"entrypoints": {
"client": [
"com.seibel.lod.fabric.Main"
],
"modmenu": [
"com.seibel.lod.fabric.wrappers.config.ModMenuIntegration"
]
},
"mixins": [
"fabric.lod.mixins.json"
],
"accessWidener" : "lod.accesswidener",
"depends": {
"fabricloader": "*",
"fabric-lifecycle-events-v1": "*",
"fabric-key-binding-api-v1": "*",
"fabric-networking-api-v1": "*",
"minecraft": $compatible_minecraft_versions,
"java": ">=${java_version}"
},
"custom": {
"modmenu": {
"links": {
"modmenu.discord": "https://discord.gg/xAB8G4cENx"
}
}
}
}
-293
View File
@@ -1,293 +0,0 @@
plugins {
id "com.github.johnrengelman.shadow" version "7.1.0"
}
apply plugin: "java"
apply plugin: "architectury-plugin"
apply plugin: "maven-publish"
apply plugin: "dev.architectury.loom"
archivesBaseName = rootProject.archives_base_name
version = rootProject.mod_version //FIXME: HERE repeated def
group = rootProject.maven_group
version = rootProject.mod_version+"-"+rootProject.minecraft_version+"-"+new Date().format("yyyy_MM_dd_HH_mm")
loom {
silentMojangMappingsLicense()
accessWidenerPath.set(project(":common").file("src/main/resources/${acsessWidenerVersion}.lod.accesswidener"))
forge {
convertAccessWideners.set(true)
extraAccessWideners.add("lod.accesswidener")
mixinConfigs("lod.mixins.json")
}
}
architectury {
platformSetupLoomIde()
forge()
}
configurations {
common
shadowMe
implementation.extendsFrom shadowMe
compileClasspath.extendsFrom common
runtimeClasspath.extendsFrom common
developmentForge.extendsFrom common
}
java {
withSourcesJar()
}
jar.dependsOn(project(":core").remapJar)
remapSourcesJar.dependsOn(project(":core").remapJar)
def addMod(path, enabled) {
if (enabled == "2")
dependencies { modImplementation(path) }
else if (enabled == "1")
dependencies { modCompileOnly(path) }
}
dependencies {
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)
if (rootProject.minecraft_version != "1.19" && rootProject.minecraft_version != "1.19.1")
parchment("org.parchmentmc.data:parchment-${rootProject.minecraft_version}:${rootProject.parchment_version}@zip")
else
parchment("org.parchmentmc.data:parchment-1.18.2:${rootProject.parchment_version}@zip") // As 1.19 dosnt have parchment mappings yet, we use 1.18.2 mapping
}
//Manifold
annotationProcessor "systems.manifold:manifold-preprocessor:${rootProject.manifold_version}"
// Toml
implementation("com.electronwill.night-config:toml:${rootProject.toml_version}")
common(project(":core")) { transitive false }
// Forge loader
forge "net.minecraftforge:forge:${rootProject.minecraft_version}-${rootProject.forge_version}"
// Starlight
addMod("curse.maven:starlight-forge-526854:${rootProject.starlight_version_forge}", rootProject.enable_starlight_forge)
annotationProcessor "org.spongepowered:mixin:0.8.4:processor"
addMod("curse.maven:TerraForged-363820:${rootProject.terraforged_version}", rootProject.enable_terraforged)
common(project(path: ":common", configuration: "namedElements")) { transitive false }
shadowMe(project(path: ":common", configuration: "transformProductionForge")) { transitive = false }
shadowMe files(project(":core").file("build/libs/DistantHorizons-${rootProject.mod_version}.jar"))
// forgeDependencies(project(":core")) { transitive false }
// Toml
shadowMe("com.electronwill.night-config:toml:${rootProject.toml_version}") {}
// Compression
forgeDependencies('org.tukaani:xz:1.9')
forgeDependencies('org.apache.commons:commons-compress:1.21')
shadowMe 'org.tukaani:xz:1.9'
shadowMe 'org.apache.commons:commons-compress:1.21'
}
// Copies the correct accesswidener and renames it
task copyAccessWidener(type: Copy) {
from project(":common").file("src/main/resources/${rootProject.acsessWidenerVersion}.lod.accesswidener")
into(file("build/resources/main"))
rename "${rootProject.acsessWidenerVersion}.lod.accesswidener", "lod.accesswidener"
}
task copyCoreResources(type: Copy) {
from fileTree(project(":core").file("src/main/resources"))
into file("build/resources/main")
}
task copyCommonResources(type: Copy) {
from fileTree(project(":common").file("src/main/resources"))
into file("build/resources/main")
}
// Put stuff from gradle.properties into the mod info
processResources {
dependsOn(copyAccessWidener)
dependsOn(copyCoreResources)
dependsOn(copyCommonResources)
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 replaceProperties = [
version : mod_version,
mod_name : mod_name,
authors : mod_authors,
description : mod_description,
homepage : mod_homepage,
source : mod_source,
issues : mod_issues,
minecraft_version : minecraft_version,
compatible_minecraft_versions: compatible_minecraft_versions,
java_version : java_version
]
// 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
replaceProperties.put 'project', project
filesMatching(resourceTargets) {
expand replaceProperties
}
intoTargets.each { target ->
if (file(target).exists()) {
copy {
from(sourceSets.main.resources) {
include resourceTargets
expand replaceProperties
}
into target
}
}
}
}
shadowJar {
dependencies {
exclude(dependency("net.fabricmc:fabric-loader:${rootProject.fabric_loader_version}"))
}
exclude "fabric.mod.json"
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' // This is already included with forge
relocate 'com.seibel.lod.common', 'forge.com.seibel.lod.common'
classifier "dev-shadow"
}
remapJar {
input.set shadowJar.archiveFile
dependsOn shadowJar
classifier null
}
jar {
manifest {
attributes 'Implementation-Title': rootProject.archives_base_name,
'Implementation-Version': rootProject.mod_version,
'Main-Class': 'com.seibel.lod.core.JarMain' // When changing the main of the jar change this line
}
classifier "dev"
}
sourcesJar {
def commonSources = project(":common").sourcesJar
dependsOn commonSources
from commonSources.archiveFile.map { zipTree(it) }
}
components.java {
withVariantsFromConfiguration(project.configurations.shadowRuntimeElements) {
skip()
}
}
publishing {
publications {
mavenForge(MavenPublication) {
artifactId = rootProject.archives_base_name + "-" + project.name
from components.java
}
}
// See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing.
repositories {
// Add repositories to publish to here.
}
}
task printConfigurations {
doLast {task ->
println "Project Name: $name configurations:"
configurations.each {
println " $it.name"
}
}
}
repositories {
mavenCentral()
// For parchment mappings
maven { url "https://maven.parchmentmc.org" }
// used to download and compile dependencies from git repos
maven { url 'https://jitpack.io' }
// For Manifold Preprocessor
maven { url 'https://oss.sonatype.org/content/repositories/snapshots/' }
// Required for importing Modrinth mods
maven {
name = "Modrinth"
url = "https://api.modrinth.com/maven"
content {
includeGroup "maven.modrinth"
}
}
// Required for importing CursedForge mods
maven {
url "https://www.cursemaven.com"
content {
includeGroup "curse.maven"
}
}
// These 2 are for importing mods that arnt on CursedForge, Modrinth, GitHub, GitLab or anywhere opensource
flatDir {
dirs "${rootDir}/mods/fabric"
content {
includeGroup "fabric-mod"
}
}
flatDir {
dirs "${rootDir}/mods/forge"
content {
includeGroup "forge-mod"
}
}
}
tasks.withType(JavaCompile) {
// Add Manifold Preprocessor
// def excapedMCVersion = rootProject.minecraft_version.replace(".", "_")
// options.compilerArgs += ['-Xplugin:Manifold', "-AMC_VERSION_${excapedMCVersion}"]
//
//options.compilerArgs += ['-deprecation']
//options.compilerArgs += ['-verbose']
//options.compilerArgs += ['-Xlint:unchecked']
//options.compilerArgs += ['-Xdiags:verbose']
//options.compilerArgs += ['-Xprint']
//options.compilerArgs += ['-XprintProcessorInfo']
//options.compilerArgs += ['-XprintRounds']
// println options.compilerArgs
// Set the java version
options.compilerArgs += ['-Xplugin:Manifold']
options.release = rootProject.java_version as Integer //FIXME: This warning??
// TODO: make everything use java 8
// options.release = 8 // Use Java 8 for everything so back porting is easier?
}
-1
View File
@@ -1 +0,0 @@
loom.platform=forge
@@ -1,155 +0,0 @@
/*
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
* licensed under the GNU GPL 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 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.forge;
import com.seibel.lod.core.api.ClientApi;
import com.seibel.lod.core.api.EventApi;
import com.seibel.lod.core.wrapperInterfaces.chunk.IChunkWrapper;
import net.minecraft.client.gui.screens.TitleScreen;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.world.entity.player.Player;
import org.lwjgl.glfw.GLFW;
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 net.minecraft.client.Minecraft;
import net.minecraftforge.client.event.InputEvent;
import net.minecraftforge.event.TickEvent;
#if PRE_MC_1_19_1
import net.minecraftforge.event.world.BlockEvent;
import net.minecraftforge.event.world.ChunkEvent;
import net.minecraftforge.event.world.WorldEvent;
#else
import net.minecraftforge.event.level.BlockEvent;
import net.minecraftforge.event.level.ChunkEvent;
import net.minecraftforge.event.level.LevelEvent;
#endif
import net.minecraftforge.eventbus.api.SubscribeEvent;
/**
* This handles all events sent to the client,
* and is the starting point for most of the mod.
*
* @author James_Seibel
* @version 11-12-2021
*/
public class ForgeClientProxy
{
private final EventApi eventApi = EventApi.INSTANCE;
private final ClientApi clientApi = ClientApi.INSTANCE;
@SubscribeEvent
public void serverTickEvent(TickEvent.ServerTickEvent event)
{
if (event.phase != TickEvent.Phase.START) return;
eventApi.serverTickEvent();
}
@SubscribeEvent
public void chunkLoadEvent(ChunkEvent.Load event)
{
#if PRE_MC_1_19_1
clientApi.clientChunkLoadEvent(new ChunkWrapper(event.getChunk(), event.getWorld()), WorldWrapper.getWorldWrapper(event.getWorld()));
#else
clientApi.clientChunkLoadEvent(new ChunkWrapper(event.getChunk(), event.getLevel()), WorldWrapper.getWorldWrapper(event.getLevel()));
#endif
}
@SubscribeEvent
#if PRE_MC_1_19_1
public void worldSaveEvent(WorldEvent.Save event)
#else
public void worldSaveEvent(LevelEvent.Save event)
#endif
{
eventApi.worldSaveEvent();
}
/** This is also called when a new dimension loads */
@SubscribeEvent
#if PRE_MC_1_19_1
public void worldLoadEvent(WorldEvent.Load event)
#else
public void worldLoadEvent(LevelEvent.Load event)
#endif
{
if (Minecraft.getInstance().screen instanceof TitleScreen) return;
#if PRE_MC_1_19_1
if (event.getWorld() != null) {
eventApi.worldLoadEvent(WorldWrapper.getWorldWrapper(event.getWorld()));
}
#else
if (event.getLevel() != null) {
eventApi.worldLoadEvent(WorldWrapper.getWorldWrapper(event.getLevel()));
}
#endif
}
@SubscribeEvent
#if PRE_MC_1_19_1
public void worldUnloadEvent(WorldEvent.Unload event)
{
eventApi.worldUnloadEvent(WorldWrapper.getWorldWrapper(event.getWorld()));
}
#else
public void worldUnloadEvent(LevelEvent.Unload event)
{
eventApi.worldUnloadEvent(WorldWrapper.getWorldWrapper(event.getLevel()));
}
#endif
@SubscribeEvent
public void blockChangeEvent(BlockEvent event)
{
// we only care about certain block events
if (event.getClass() == BlockEvent.BreakEvent.class ||
event.getClass() == BlockEvent.EntityPlaceEvent.class ||
event.getClass() == BlockEvent.EntityMultiPlaceEvent.class ||
event.getClass() == BlockEvent.FluidPlaceBlockEvent.class ||
event.getClass() == BlockEvent.PortalSpawnEvent.class)
{
#if PRE_MC_1_19_1
IChunkWrapper chunk = new ChunkWrapper(event.getWorld().getChunk(event.getPos()), event.getWorld());
DimensionTypeWrapper dimType = DimensionTypeWrapper.getDimensionTypeWrapper(event.getWorld().dimensionType());
#else
IChunkWrapper chunk = new ChunkWrapper(event.getLevel().getChunk(event.getPos()), event.getLevel());
DimensionTypeWrapper dimType = DimensionTypeWrapper.getDimensionTypeWrapper(event.getLevel().dimensionType());
#endif
// recreate the LOD where the blocks were changed
eventApi.blockChangeEvent(chunk, dimType);
}
}
@SubscribeEvent
public void onKeyInput(#if PRE_MC_1_19_1 InputEvent.KeyInputEvent event #else InputEvent.Key event #endif)
{
if (Minecraft.getInstance().player == null) return;
if (event.getAction() != GLFW.GLFW_PRESS) return;
clientApi.keyPressedEvent(event.getKey());
}
}
@@ -1,150 +0,0 @@
/*
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
* licensed under the GNU GPL 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 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.forge;
import com.seibel.lod.common.LodCommonMain;
import com.seibel.lod.common.forge.LodForgeMethodCaller;
import com.seibel.lod.common.wrappers.config.ConfigGui;
import com.seibel.lod.common.wrappers.minecraft.MinecraftClientWrapper;
import com.seibel.lod.core.ModInfo;
import com.seibel.lod.core.api.ApiShared;
import com.seibel.lod.core.handlers.ReflectionHandler;
import com.seibel.lod.core.handlers.dependencyInjection.ModAccessorHandler;
import com.seibel.lod.core.wrapperInterfaces.modAccessor.IOptifineAccessor;
import com.seibel.lod.forge.wrappers.ForgeDependencySetup;
import com.seibel.lod.forge.wrappers.modAccessor.OptifineAccessor;
import net.minecraft.client.renderer.block.model.BakedQuad;
import net.minecraft.core.Direction;
import net.minecraft.world.level.ColorResolver;
import net.minecraft.world.level.biome.Biome;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.fml.ModLoadingContext;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
import net.minecraftforge.fml.loading.FMLLoader;
#if PRE_MC_1_17_1
import net.minecraftforge.fml.ExtensionPoint;
#elif MC_1_17_1
import net.minecraftforge.fmlclient.ConfigGuiHandler;
#elif POST_MC_1_19_1
import net.minecraftforge.client.ConfigScreenHandler;
#else // 1.18+ untill 1.19
import net.minecraftforge.client.ConfigGuiHandler;
#endif
// these imports change due to forge refactoring classes in 1.19
#if POST_MC_1_19_1
import net.minecraft.util.RandomSource;
import net.minecraft.client.renderer.RenderType;
import net.minecraftforge.client.model.data.ModelData;
#else
import net.minecraftforge.client.model.data.ModelDataMap;
import java.util.Random;
#endif
import java.util.List;
/**
* Initialize and setup the Mod. <br>
* If you are looking for the real start of the mod
* check out the ClientProxy.
*
* @author James Seibel
* @version 11-21-2021
*/
@Mod(ModInfo.ID)
public class ForgeMain implements LodForgeMethodCaller
{
public static ForgeClientProxy forgeClientProxy;
private void init(final FMLCommonSetupEvent event)
{
// make sure the dependencies are set up before the mod needs them
LodCommonMain.initConfig();
LodCommonMain.startup(this, !FMLLoader.getDist().isClient());
ForgeDependencySetup.createInitialBindings();
ForgeDependencySetup.finishBinding();
ApiShared.LOGGER.info("Distant Horizons initializing...");
}
public ForgeMain()
{
// Register the methods for server and other game events we are interested in
FMLJavaModLoadingContext.get().getModEventBus().addListener(this::init);
FMLJavaModLoadingContext.get().getModEventBus().addListener(this::onClientStart);
}
private void onClientStart(final FMLClientSetupEvent event)
{
if (ReflectionHandler.instance.optifinePresent()) {
ModAccessorHandler.bind(IOptifineAccessor.class, new OptifineAccessor());
}
ModAccessorHandler.finishBinding();
#if PRE_MC_1_17_1
ModLoadingContext.get().registerExtensionPoint(ExtensionPoint.CONFIGGUIFACTORY,
() -> (client, parent) -> ConfigGui.getScreen(parent, ""));
#elif POST_MC_1_19_1
ModLoadingContext.get().registerExtensionPoint(ConfigScreenHandler.ConfigScreenFactory.class,
() -> new ConfigScreenHandler.ConfigScreenFactory((client, parent) -> ConfigGui.getScreen(parent, "")));
#else
ModLoadingContext.get().registerExtensionPoint(ConfigGuiHandler.ConfigGuiFactory.class,
() -> new ConfigGuiHandler.ConfigGuiFactory((client, parent) -> ConfigGui.getScreen(parent, "")));
#endif
forgeClientProxy = new ForgeClientProxy();
MinecraftForge.EVENT_BUS.register(forgeClientProxy);
}
#if PRE_MC_1_19_1
private final ModelDataMap modelData = new ModelDataMap.Builder().build();
#else
private final ModelData modelData = ModelData.EMPTY;
#endif
@Override
#if PRE_MC_1_19_1
public List<BakedQuad> getQuads(MinecraftClientWrapper mc, Block block, BlockState blockState, Direction direction, Random random) {
return mc.getModelManager().getBlockModelShaper().getBlockModel(block.defaultBlockState()).getQuads(blockState, direction, random, modelData);
}
#else
public List<BakedQuad> getQuads(MinecraftClientWrapper mc, Block block, BlockState blockState, Direction direction, RandomSource random)
{
return mc.getModelManager().getBlockModelShaper().getBlockModel(block.defaultBlockState()).getQuads(blockState, direction, random, modelData #if POST_MC_1_19_1, RenderType.solid() #endif);
}
#endif
@Override
public int colorResolverGetColor(ColorResolver resolver, Biome biome, double x, double z) {
#if MC_1_17_1_I_THINK_ITS_FIXED?
return resolver.m_130045_(biome, x, z);
#else
return resolver.getColor(biome, x, z);
#endif
}
}
@@ -1,58 +0,0 @@
/*
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
* licensed under the GNU GPL 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 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.forge.mixins;
import com.seibel.lod.core.api.ApiShared;
import org.spongepowered.asm.mixin.Mixin;
import net.minecraft.world.level.chunk.ChunkGenerator;
#if PRE_MC_1_18_1
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
import net.minecraft.core.BlockPos;
import net.minecraft.server.level.WorldGenRegion;
import net.minecraft.world.level.StructureFeatureManager;
import net.minecraft.world.level.biome.Biome;
import net.minecraft.world.level.levelgen.WorldgenRandom;
@Mixin(ChunkGenerator.class)
public class MixinChunkGenerator {
@Redirect(method = "applyBiomeDecoration", at = @At(
value = "INVOKE",
target = "Lnet/minecraft/world/level/biome/Biome;generate(Lnet/minecraft/world/level/StructureFeatureManager;"
+ "Lnet/minecraft/world/level/chunk/ChunkGenerator;Lnet/minecraft/server/level/WorldGenRegion;J"
+ "Lnet/minecraft/world/level/levelgen/WorldgenRandom;Lnet/minecraft/core/BlockPos;)V"
))
private void wrapBiomeGenerateCall(Biome biome, StructureFeatureManager structFeatManager, ChunkGenerator generator,
WorldGenRegion genRegion, long l, WorldgenRandom random, BlockPos pos) {
synchronized(ChunkGenerator.class) {
//ApiShared.LOGGER.info("Generating Biome {} and acquired lock.", biome.getRegistryName());
biome.generate(structFeatManager, (ChunkGenerator)(Object)this, genRegion, l, random, pos);
}
//ApiShared.LOGGER.info("Released lock. Biome {} generated.", biome.getRegistryName());
}
}
#else
@Mixin(ChunkGenerator.class)
public class MixinChunkGenerator {}
#endif
@@ -1,24 +0,0 @@
package com.seibel.lod.forge.mixins;
import com.seibel.lod.core.render.F3Screen;
import net.minecraft.client.gui.components.DebugScreenOverlay;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import java.util.List;
@Mixin(DebugScreenOverlay.class)
public class MixinDebugScreenOverlay {
@Inject(method = "getSystemInformation", at = @At("RETURN"))
private void addCustomF3(CallbackInfoReturnable<List<String>> cir) {
List<String> messages = cir.getReturnValue();
for (String i: F3Screen.f3List) {
messages.add(i);
}
}
}

Some files were not shown because too many files have changed in this diff Show More